Version 1.14.0-dev.7.0

Merge commit 'cd21da1d980b3e44c1c3554ce9ba9faeca7fffc5' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b61bead..308dfa5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,10 @@
 ## 1.14.0
 
 ### Core library changes
+* `dart:async`
+  * Added `Future.any` static method.
+  * Added `Stream.fromFutures` constructor.
+
 * `dart:convert`
   * `Base64Decoder.convert` now takes optional `start` and `end` parameters.
 
@@ -53,12 +57,39 @@
   * `pub global run` now detects when a global executable's SDK constraint is no
     longer met and errors out, rather than trying to run the executable anyway.
 
+  * Pub commands that check whether the lockfile is up-to-date (`pub run`, `pub
+    deps`, `pub serve`, and `pub build`) now do additional verification. They
+    ensure that any path dependencies' pubspecs haven't been changed, and they
+    ensure that the current SDK version is compatible with all dependencies.
+
   * Fixed a crashing bug when using `pub global run` on a global script that
     didn't exist.
 
   * Fixed a crashing bug when a pubspec contains a dependency without a source
     declared.
 
+## 1.13.2 - 2016-01-06
+
+Patch release, resolves one issue:
+
+* dart2js: Stack traces are not captured correctly (SDK issue [25235]
+(https://github.com/dart-lang/sdk/issues/25235))
+
+## 1.13.1 - 2015-12-17
+
+Patch release, resolves three issues:
+
+* VM type propagation fix: Resolves a potential crash in the Dart VM (SDK commit
+ [dff13be]
+(https://github.com/dart-lang/sdk/commit/dff13bef8de104d33b04820136da2d80f3c835d7))
+
+* dart2js crash fix: Resolves a crash in pkg/js and dart2js (SDK issue [24974]
+(https://github.com/dart-lang/sdk/issues/24974))
+
+* Pub get crash on ARM: Fixes a crash triggered when running 'pub get' on ARM
+ processors such as those on a Raspberry Pi (SDK issue [24855]
+(https://github.com/dart-lang/sdk/issues/24855))
+
 ## 1.13.0 - 2015-11-18
 
 ### Core library changes
diff --git a/DEPS b/DEPS
index e041804..fbe59dc 100644
--- a/DEPS
+++ b/DEPS
@@ -38,7 +38,7 @@
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
   "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
-  "dartdoc_tag" : "@v0.8.4",
+  "dartdoc_tag" : "@v0.8.5",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.2",
   "dev_compiler_rev": "@0.1.9",
@@ -67,7 +67,7 @@
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "plugin_tag": "@0.1.0",
   "pool_tag": "@1.2.1",
-  "pub_rev": "@a1dd3484795b2bc221aaa8d007f3162251b3c08e",
+  "pub_rev": "@57a17f2567d1ff3325960d0960f939fa243b5fd7",
   "pub_cache_tag": "@v0.1.0",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
diff --git a/LICENSE b/LICENSE
index fa95f12..68bcabf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -9,7 +9,6 @@
 bzip2 - in third_party/bzip2
 Commons IO - in third_party/commons-io
 Commons Lang in third_party/commons-lang
-dromaeo - in samples/third_party/dromaeo
 Eclipse - in third_party/eclipse
 gsutil - in third_party/gsutil
 Guava - in third_party/guava
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 3850f20..fb3a9e4 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -2435,6 +2435,7 @@
 \item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numeric or string value or to \NULL{}.
 \item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code{$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$},  \code{$e_1  >  e_2$}, \code{$e_1  <  e_2$}, \code{$e_1$ $>$= $e_2$}, \code{$e_1$ $<$= $e_2$} or \code{$e_1$ \% $e_2$},  where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to a numeric value  or to \NULL{}.
 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $e_3$ are constant expressions and $e_1$ evaluates to a boolean value.
+\item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are constant expressions.
 \item An expression of the form \code{$e$.length} where $e$ is a constant expression that evaluates to a string value.
 \end{itemize}
 
diff --git a/pkg/analysis_server/.analysis_options b/pkg/analysis_server/.analysis_options
new file mode 100644
index 0000000..7b230dd
--- /dev/null
+++ b/pkg/analysis_server/.analysis_options
@@ -0,0 +1,4 @@
+linter:
+  rules:
+    - unnecessary_brace_in_string_interp
+    - empty_constructor_bodies
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index b20b660..f2c4df2 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -2869,7 +2869,13 @@
           An enumeration of the kinds of elements.
         </p>
         
-      <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dt class="value">UNIT_TEST_TEST</dt><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_ExecutableFile">ExecutableFile: object</a></dt><dd>
+      <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dd>
+            
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </dd><dt class="value">UNIT_TEST_TEST</dt><dd>
+            
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </dd><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_ExecutableFile">ExecutableFile: object</a></dt><dd>
         <p>
           A description of an executable file.
         </p>
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index e931ba3..d90344f 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -9964,8 +9964,14 @@
 
   static const TYPE_PARAMETER = const ElementKind._("TYPE_PARAMETER");
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   static const UNIT_TEST_GROUP = const ElementKind._("UNIT_TEST_GROUP");
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   static const UNIT_TEST_TEST = const ElementKind._("UNIT_TEST_TEST");
 
   static const UNKNOWN = const ElementKind._("UNKNOWN");
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index 9afabda..85aabea 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -69,13 +69,8 @@
    * Begin serving HTTP requests over the given port.
    */
   void serveHttp(int port) {
-    try {
-      _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port);
-      _server.then(_handleServer);
-    } catch (exception) {
-      // We were unable to start the server, and there's nothing we can do about
-      // it.
-    }
+    _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port);
+    _server.then(_handleServer).catchError((_) {/* Ignore errors. */});
   }
 
   /**
@@ -91,8 +86,8 @@
   /**
    * Attach a listener to a newly created HTTP server.
    */
-  void _handleServer(HttpServer httServer) {
-    httServer.listen((HttpRequest request) {
+  void _handleServer(HttpServer httpServer) {
+    httpServer.listen((HttpRequest request) {
       List<String> updateValues = request.headers[HttpHeaders.UPGRADE];
       if (updateValues != null && updateValues.indexOf('websocket') >= 0) {
         WebSocketTransformer.upgrade(request).then((WebSocket websocket) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index cfe0ca7..602503e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -204,9 +204,7 @@
   @override
   Future<List<Directive>> resolveDirectives() async {
     CompilationUnit libUnit;
-    if (librarySource == source) {
-      libUnit = target.unit;
-    } else if (librarySource != null) {
+    if (librarySource != null) {
       // TODO(danrubel) only resolve the directives
       const RESOLVE_DIRECTIVES_TAG = 'resolve directives';
       performance.logStartTime(RESOLVE_DIRECTIVES_TAG);
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 0f4fc15..7260013 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -1252,6 +1252,7 @@
           _writeOption(
               buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
           _writeOption(buffer, 'Cache size', options.cacheSize);
+          _writeOption(buffer, 'Enable async support', options.enableAsync);
           _writeOption(
               buffer, 'Enable generic methods', options.enableGenericMethods);
           _writeOption(buffer, 'Enable strict call checks',
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 082f28d..f6eff47 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -316,6 +316,7 @@
     - 'test/**'
   language:
     enableGenericMethods: true
+    enableAsync: false
   errors:
     unused_local_variable: false
 linter:
@@ -338,6 +339,7 @@
     // * from `_embedder.yaml`:
     expect(context.analysisOptions.strongMode, isTrue);
     expect(context.analysisOptions.enableSuperMixins, isTrue);
+    expect(context.analysisOptions.enableAsync, isFalse);
     // * from `.analysis_options`:
     expect(context.analysisOptions.enableGenericMethods, isTrue);
     // * verify tests are excluded
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
index 14783c3..0291a15 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
@@ -63,8 +63,14 @@
 
   public static final String TYPE_PARAMETER = "TYPE_PARAMETER";
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   public static final String UNIT_TEST_GROUP = "UNIT_TEST_GROUP";
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   public static final String UNIT_TEST_TEST = "UNIT_TEST_TEST";
 
   public static final String UNKNOWN = "UNKNOWN";
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 3bb6cfe..c26da51 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -2621,8 +2621,14 @@
           <value><code>SETTER</code></value>
           <value><code>TOP_LEVEL_VARIABLE</code></value>
           <value><code>TYPE_PARAMETER</code></value>
-          <value><code>UNIT_TEST_GROUP</code></value>
-          <value><code>UNIT_TEST_TEST</code></value>
+          <value>
+            <code>UNIT_TEST_GROUP</code>
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </value>
+          <value>
+            <code>UNIT_TEST_TEST</code>
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </value>
           <value><code>UNKNOWN</code></value>
         </enum>
       </type>
diff --git a/pkg/analyzer/.analysis_options b/pkg/analyzer/.analysis_options
new file mode 100644
index 0000000..7b230dd
--- /dev/null
+++ b/pkg/analyzer/.analysis_options
@@ -0,0 +1,4 @@
+linter:
+  rules:
+    - unnecessary_brace_in_string_interp
+    - empty_constructor_bodies
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 49607dc..548dc1d 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -131,13 +131,20 @@
  */
 abstract class FunctionType implements ParameterizedType {
   /**
-   * The type parameters of this generic function. For example `<T> T -> T`.
+   * Deprecated: use [typeFormals].
+   */
+  @deprecated
+  List<TypeParameterElement> get boundTypeParameters;
+
+  /**
+   * The formal type parameters of this generic function.
+   * For example `<T> T -> T`.
    *
    * These are distinct from the [typeParameters] list, which contains type
    * parameters from surrounding contexts, and thus are free type variables from
    * the perspective of this function type.
    */
-  List<TypeParameterElement> get boundTypeParameters;
+  List<TypeParameterElement> get typeFormals;
 
   /**
    * Return a map from the names of named parameters to the types of the named
@@ -569,7 +576,7 @@
    */
   // TODO(jmesserly): introduce a new "instantiate" and deprecate this.
   // The new "instantiate" should work similar to FunctionType.instantiate,
-  // which uses [boundTypeParameters] to model type parameters that haven't been
+  // which uses [typeFormals] to model type parameters that haven't been
   // filled in yet. Those are kept separate from already-substituted type
   // parameters or free variables from the enclosing scopes, which allows nested
   // generics to work, such as a generic method in a generic class.
@@ -590,7 +597,16 @@
 }
 
 /**
- * A type with type parameters, such as a class or function type alias.
+ * A type that can track substituted type parameters, either for itself after
+ * instantiation, or from a surrounding context.
+ *
+ * For example, given a class `Foo<T>`, after instantiation with S for T, it
+ * will track the substitution `{S/T}`.
+ *
+ * This substitution will be propagated to its members. For example, say our
+ * `Foo<T>` class has a field `T bar;`. When we look up this field, we will get
+ * back a [FieldElement] that tracks the substituted type as `{S/T}T`, so when
+ * we ask for the field type we will get`S`.
  *
  * Clients may not extend, implement or mix-in this class.
  */
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 1c96ef0..dd6ee41 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -99,14 +99,14 @@
    */
   void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
     if (containsOnlyWhitespace(docs)) return;
-    writeln(codeGeneratorSettings.docCommentStartMarker);
+    if (codeGeneratorSettings.docCommentStartMarker != null) writeln(codeGeneratorSettings.docCommentStartMarker);
     int width = codeGeneratorSettings.commentLineLength;
     bool javadocStyle = codeGeneratorSettings.languageName == 'java';
     indentBy(codeGeneratorSettings.docCommentLineLeader, () {
       write(nodesToText(docs, width - _state.indent.length, javadocStyle,
           removeTrailingNewLine: removeTrailingNewLine));
     });
-    writeln(codeGeneratorSettings.docCommentEndMarker);
+    if (codeGeneratorSettings.docCommentEndMarker != null) writeln(codeGeneratorSettings.docCommentEndMarker);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index ac3ace6..4714557 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -253,6 +253,7 @@
         this._options.enableStrictCallChecks !=
             options.enableStrictCallChecks ||
         this._options.enableGenericMethods != options.enableGenericMethods ||
+        this._options.enableAsync != options.enableAsync ||
         this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
@@ -266,6 +267,7 @@
     this._options.enableGenericMethods = options.enableGenericMethods;
     this._options.enableAssertMessage = options.enableAssertMessage;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
+    this._options.enableAsync = options.enableAsync;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
@@ -486,27 +488,29 @@
 
   @override
   bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
-    AnalysisTarget target = entry.target;
-    // TYPE_PROVIDER
-    if (target is AnalysisContextTarget && result == TYPE_PROVIDER) {
-      DartSdk dartSdk = sourceFactory.dartSdk;
-      if (dartSdk != null) {
-        AnalysisContext sdkContext = dartSdk.context;
-        if (!identical(sdkContext, this) &&
-            sdkContext is InternalAnalysisContext) {
-          return sdkContext.aboutToComputeResult(entry, result);
+    return PerformanceStatistics.summary.makeCurrentWhile(() {
+      AnalysisTarget target = entry.target;
+      // TYPE_PROVIDER
+      if (target is AnalysisContextTarget && result == TYPE_PROVIDER) {
+        DartSdk dartSdk = sourceFactory.dartSdk;
+        if (dartSdk != null) {
+          AnalysisContext sdkContext = dartSdk.context;
+          if (!identical(sdkContext, this) &&
+              sdkContext is InternalAnalysisContext) {
+            return sdkContext.aboutToComputeResult(entry, result);
+          }
         }
       }
-    }
-    // A result for a Source.
-    Source source = target.source;
-    if (source != null) {
-      InternalAnalysisContext context = _cache.getContextFor(source);
-      if (!identical(context, this)) {
-        return context.aboutToComputeResult(entry, result);
+      // A result for a Source.
+      Source source = target.source;
+      if (source != null) {
+        InternalAnalysisContext context = _cache.getContextFor(source);
+        if (!identical(context, this)) {
+          return context.aboutToComputeResult(entry, result);
+        }
       }
-    }
-    return false;
+      return false;
+    });
   }
 
   @override
@@ -1059,7 +1063,7 @@
 
   @override
   AnalysisResult performAnalysisTask() {
-    return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
+    return PerformanceStatistics.performAnalysis.makeCurrentWhile(() {
       _evaluatePendingFutures();
       bool done = !driver.performAnalysisTask();
       List<ChangeNotice> notices = _getChangeNotices(done);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 00e4fe2..71030e7 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2613,6 +2613,16 @@
   void shareParameters(List<ParameterElement> parameters) {
     this._parameters = parameters;
   }
+
+  /**
+   * Set the type parameters defined by this type alias to the given
+   * [parameters] without becoming the parent of the parameters. This should
+   * only be used by the [TypeResolverVisitor] when creating a synthetic type
+   * alias.
+   */
+  void shareTypeParameters(List<TypeParameterElement> typeParameters) {
+    this._typeParameters = typeParameters;
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 9599775..75dcee6 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -339,15 +339,21 @@
 }
 
 /**
+ * Deprecated: this type is no longer used. Use
+ * [MethodInvocation.staticInvokeType] to get the instantiated type of a generic
+ * method invocation.
+ *
  * An element of a generic function, where the type parameters are known.
  */
 // TODO(jmesserly): the term "function member" is a bit weird, but it allows
 // a certain consistency.
+@deprecated
 class FunctionMember extends ExecutableMember implements FunctionElement {
   /**
    * Initialize a newly created element to represent a function, based on the
    * [baseElement], with the corresponding function [type].
    */
+  @deprecated
   FunctionMember(FunctionElement baseElement, [DartType type])
       : super(baseElement, null, type);
 
@@ -674,12 +680,6 @@
   @override
   SourceRange get visibleRange => baseElement.visibleRange;
 
-  // TODO(jmesserly): this equality is broken. It should consider the defining
-  // type as well, otherwise we're dropping the substitution.
-  @override
-  bool operator ==(Object object) =>
-      object is ParameterMember && baseElement == object.baseElement;
-
   @override
   accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
 
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 03c361d..b804339 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -177,7 +177,7 @@
   /**
    * True if this type is the result of instantiating type parameters (and thus
    * any type parameters bound by the typedef should be considered part of
-   * [typeParameters] rather than [boundTypeParameters]).
+   * [typeParameters] rather than [typeFormals]).
    */
   final bool _isInstantiated;
 
@@ -200,9 +200,9 @@
    * Initialize a newly created function type to be declared by the given
    * [element], with the given [name] and [typeArguments].
    */
-  FunctionTypeImpl.elementWithNameAndArgs(
-      Element element, String name, List<DartType> typeArguments)
-      : this._(element, name, null, typeArguments, true);
+  FunctionTypeImpl.elementWithNameAndArgs(Element element, String name,
+      List<DartType> typeArguments, bool isInstantiated)
+      : this._(element, name, null, typeArguments, isInstantiated);
 
   /**
    * Initialize a newly created function type to be declared by the given
@@ -216,22 +216,8 @@
    * Private constructor.
    */
   FunctionTypeImpl._(TypeParameterizedElement element, String name,
-      this.prunedTypedefs, List<DartType> typeArguments, this._isInstantiated)
-      : super(element, name) {
-    if (typeArguments == null) {
-      // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
-      // make it generic, which will allow it to return List<DartType> instead
-      // of List<TypeParameterType>.
-      if (typeParameters.isEmpty) {
-        typeArguments = DartType.EMPTY_LIST;
-      } else {
-        typeArguments = new List<DartType>.from(
-            typeParameters.map((t) => t.type),
-            growable: false);
-      }
-    }
-    _typeArguments = typeArguments;
-  }
+      this.prunedTypedefs, this._typeArguments, this._isInstantiated)
+      : super(element, name);
 
   /**
    * Return the base parameter elements of this function element.
@@ -243,8 +229,12 @@
    */
   DartType get baseReturnType => element.returnType;
 
+  @deprecated
   @override
-  List<TypeParameterElement> get boundTypeParameters {
+  List<TypeParameterElement> get boundTypeParameters => typeFormals;
+
+  @override
+  List<TypeParameterElement> get typeFormals {
     if (_isInstantiated) {
       return TypeParameterElement.EMPTY_LIST;
     } else {
@@ -350,24 +340,9 @@
   }
 
   /**
-   * The type arguments that were used to instantiate this function type, if
-   * any, otherwise this will return an empty list.
-   *
-   * Given a function type `f`:
-   *
-   *     f == f.originalFunction.instantiate(f.instantiatedTypeArguments)
-   *
-   * Will always hold.
+   * Return `true` if this type is the result of instantiating type parameters.
    */
-  List<DartType> get instantiatedTypeArguments {
-    int typeParameterCount = element.type.boundTypeParameters.length;
-    if (typeParameterCount == 0) {
-      return DartType.EMPTY_LIST;
-    }
-    // The substituted types at the end should be our bound type parameters.
-    int skipCount = typeArguments.length - typeParameterCount;
-    return new List<DartType>.from(typeArguments.skip(skipCount));
-  }
+  bool get isInstantiated => _isInstantiated;
 
   @override
   Map<String, DartType> get namedParameterTypes {
@@ -466,20 +441,6 @@
     return types;
   }
 
-  /**
-   * If this is an instantiation of a generic function type, this will get
-   * the original function from which it was instantiated.
-   *
-   * Otherwise, this will return `this`.
-   */
-  FunctionTypeImpl get originalFunction {
-    if (element.type.boundTypeParameters.isEmpty) {
-      return this;
-    }
-    return (element.type as FunctionTypeImpl).substitute2(typeArguments,
-        TypeParameterTypeImpl.getTypes(typeParameters), prunedTypedefs);
-  }
-
   @override
   List<ParameterElement> get parameters {
     List<ParameterElement> baseParameters = this.baseParameters;
@@ -518,7 +479,21 @@
   /**
    * A list containing the actual types of the type arguments.
    */
-  List<DartType> get typeArguments => _typeArguments;
+  List<DartType> get typeArguments {
+    if (_typeArguments == null) {
+      // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
+      // make it generic, which will allow it to return List<DartType> instead
+      // of List<TypeParameterType>.
+      if (typeParameters.isEmpty) {
+        _typeArguments = DartType.EMPTY_LIST;
+      } else {
+        _typeArguments = new List<DartType>.from(
+            typeParameters.map((t) => t.type),
+            growable: false);
+      }
+    }
+    return _typeArguments;
+  }
 
   @override
   List<TypeParameterElement> get typeParameters {
@@ -553,19 +528,19 @@
       return false;
     }
     FunctionTypeImpl otherType = object as FunctionTypeImpl;
-    if (boundTypeParameters.length != otherType.boundTypeParameters.length) {
+    if (typeFormals.length != otherType.typeFormals.length) {
       return false;
     }
     // `<T>T -> T` should be equal to `<U>U -> U`
     // To test this, we instantiate both types with the same (unique) type
     // variables, and see if the result is equal.
-    if (boundTypeParameters.isNotEmpty) {
+    if (typeFormals.isNotEmpty) {
       List<DartType> instantiateTypeArgs = new List<DartType>();
       List<DartType> variablesThis = new List<DartType>();
       List<DartType> variablesOther = new List<DartType>();
-      for (int i = 0; i < boundTypeParameters.length; i++) {
-        TypeParameterElement pThis = boundTypeParameters[i];
-        TypeParameterElement pOther = otherType.boundTypeParameters[i];
+      for (int i = 0; i < typeFormals.length; i++) {
+        TypeParameterElement pThis = typeFormals[i];
+        TypeParameterElement pOther = otherType.typeFormals[i];
         TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
             new TypeParameterElementImpl(pThis.name, -1));
         instantiateTypeArgs.add(pFresh);
@@ -578,7 +553,7 @@
           return false;
         }
       }
-      // After instantiation, they will no longer have boundTypeParameters,
+      // After instantiation, they will no longer have typeFormals,
       // so we will continue below.
       return this.instantiate(instantiateTypeArgs) ==
           otherType.instantiate(instantiateTypeArgs);
@@ -594,7 +569,7 @@
 
   @override
   void appendTo(StringBuffer buffer) {
-    if (boundTypeParameters.isNotEmpty) {
+    if (typeFormals.isNotEmpty) {
       // To print a type with type variables, first make sure we have unique
       // variable names to print.
       Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>();
@@ -610,8 +585,8 @@
       List<DartType> instantiateTypeArgs = new List<DartType>();
       List<DartType> variables = new List<DartType>();
       buffer.write("<");
-      for (TypeParameterElement e in boundTypeParameters) {
-        if (e != boundTypeParameters[0]) {
+      for (TypeParameterElement e in typeFormals) {
+        if (e != typeFormals[0]) {
           buffer.write(",");
         }
         String name = e.name;
@@ -640,7 +615,7 @@
       buffer.write(">");
 
       // Instantiate it and print the resulting type. After instantiation, it
-      // will no longer have boundTypeParameters, so we will continue below.
+      // will no longer have typeFormals, so we will continue below.
       this.instantiate(instantiateTypeArgs).appendTo(buffer);
       return;
     }
@@ -708,10 +683,10 @@
 
   @override
   FunctionTypeImpl instantiate(List<DartType> argumentTypes) {
-    if (argumentTypes.length != boundTypeParameters.length) {
+    if (argumentTypes.length != typeFormals.length) {
       throw new IllegalArgumentException(
           "argumentTypes.length (${argumentTypes.length}) != "
-          "boundTypeParameters.length (${boundTypeParameters.length})");
+          "typeFormals.length (${typeFormals.length})");
     }
     if (argumentTypes.isEmpty) {
       return this;
@@ -720,7 +695,7 @@
     // Given:
     //     {U/T} <S> T -> S
     // Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
-    // and <S> represents the boundTypeParameters.
+    // and <S> represents the typeFormals.
     //
     // Now instantiate([V]), and the result should be:
     //     {U/T, V/S} T -> S.
@@ -1019,8 +994,8 @@
       FunctionType type, Set<TypeParameterType> free) {
     // Make some fresh variables to avoid capture.
     List<DartType> typeArgs = DartType.EMPTY_LIST;
-    if (type.boundTypeParameters.isNotEmpty) {
-      typeArgs = new List<DartType>.from(type.boundTypeParameters.map((e) =>
+    if (type.typeFormals.isNotEmpty) {
+      typeArgs = new List<DartType>.from(type.typeFormals.map((e) =>
           new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1))));
 
       type = type.instantiate(typeArgs);
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 9d8ddcb..3daca75 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -5875,6 +5875,16 @@
   ExecutableElement staticElement;
 
   /**
+   * The function type of the method invocation, or `null` if the AST
+   * structure has not been resolved, or if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType staticInvokeType;
+
+  /**
    * The element associated with the function being invoked based on propagated
    * type information, or `null` if the AST structure has not been resolved or
    * the function could not be resolved.
@@ -5882,6 +5892,11 @@
   ExecutableElement propagatedElement;
 
   /**
+   * Like [staticInvokeType], but reflects propagated type information.
+   */
+  DartType propagatedInvokeType;
+
+  /**
    * Initialize a newly created function expression invocation.
    */
   FunctionExpressionInvocation(Expression function,
@@ -8088,6 +8103,21 @@
   ArgumentList _argumentList;
 
   /**
+   * The function type of the method invocation, or `null` if the AST
+   * structure has not been resolved, or if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType staticInvokeType;
+
+  /**
+   * Like [staticInvokeType], but reflects propagated type information.
+   */
+  DartType propagatedInvokeType;
+
+  /**
    * Initialize a newly created method invocation. The [target] and [operator]
    * can be `null` if there is no target.
    */
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 9f0cda0..368da2a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -9,14 +9,12 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart' as sc;
-import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * An object used by instances of [ResolverVisitor] to resolve references within
@@ -428,17 +426,26 @@
 
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    // TODO(brianwilkerson) Can we ever resolve the function being invoked?
-    Expression expression = node.function;
-    if (expression is FunctionExpression) {
-      FunctionExpression functionExpression = expression;
-      ExecutableElement functionElement = functionExpression.element;
-      ArgumentList argumentList = node.argumentList;
-      List<ParameterElement> parameters =
-          _resolveArgumentsToFunction(false, argumentList, functionElement);
-      if (parameters != null) {
-        argumentList.correspondingStaticParameters = parameters;
-      }
+    Expression function = node.function;
+    DartType staticInvokeType =
+        _resolveGenericMethod(function.staticType, node.typeArguments, node);
+    DartType propagatedInvokeType = _resolveGenericMethod(
+        function.propagatedType, node.typeArguments, node);
+
+    node.staticInvokeType = staticInvokeType;
+    node.propagatedInvokeType =
+        _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
+
+    List<ParameterElement> parameters =
+        _computeCorrespondingParameters(node.argumentList, staticInvokeType);
+    if (parameters != null) {
+      node.argumentList.correspondingStaticParameters = parameters;
+    }
+
+    parameters = _computeCorrespondingParameters(
+        node.argumentList, propagatedInvokeType);
+    if (parameters != null) {
+      node.argumentList.correspondingPropagatedParameters = parameters;
     }
     return null;
   }
@@ -639,64 +646,43 @@
         }
       }
     }
-    //
-    // Check for a generic method & apply type arguments if any were passed.
-    //
-    if (staticElement is MethodElement || staticElement is FunctionElement) {
-      FunctionType type = (staticElement as ExecutableElement).type;
-      List<TypeParameterElement> parameters = type.boundTypeParameters;
-
-      NodeList<TypeName> arguments = node.typeArguments?.arguments;
-      if (arguments != null && arguments.length != parameters.length) {
-        // Wrong number of type arguments. Ignore them
-        arguments = null;
-        _resolver.reportErrorForNode(
-            StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
-            methodName,
-            [type, parameters.length, arguments.length]);
-      }
-      if (parameters.isNotEmpty) {
-        List<DartType> typeArgs;
-        if (arguments == null) {
-          typeArgs = new List<DartType>.filled(
-              parameters.length, DynamicTypeImpl.instance);
-        } else {
-          typeArgs = new List<DartType>.from(arguments.map((n) => n.type));
-        }
-        type = type.instantiate(typeArgs);
-
-        if (staticElement is MethodMember) {
-          MethodMember member = staticElement;
-          staticElement =
-              new MethodMember(member.baseElement, member.definingType, type);
-        } else if (staticElement is MethodElement) {
-          ClassElement clazz = staticElement.enclosingElement;
-          staticElement = new MethodMember(staticElement, clazz.type, type);
-        } else {
-          staticElement =
-              new FunctionMember(staticElement as FunctionElement, type);
-        }
-      }
-    }
 
     staticElement = _convertSetterToGetter(staticElement);
     propagatedElement = _convertSetterToGetter(propagatedElement);
+
+    DartType staticInvokeType = _computeMethodInvokeType(node, staticElement);
+    DartType propagatedInvokeType =
+        _computeMethodInvokeType(node, propagatedElement);
+
     //
     // Record the results.
     //
     methodName.staticElement = staticElement;
     methodName.propagatedElement = propagatedElement;
+
+    node.staticInvokeType = staticInvokeType;
+    //
+    // Store the propagated invoke type if it's more specific than the static
+    // type.
+    //
+    // We still need to record the propagated parameter elements however,
+    // as they are used in propagatedType downwards inference of lambda
+    // parameters. So we don't want to clear the propagatedInvokeType variable.
+    //
+    node.propagatedInvokeType =
+        _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
+
     ArgumentList argumentList = node.argumentList;
-    if (staticElement != null) {
+    if (staticInvokeType != null) {
       List<ParameterElement> parameters =
-          _computeCorrespondingParameters(argumentList, staticElement);
+          _computeCorrespondingParameters(argumentList, staticInvokeType);
       if (parameters != null) {
         argumentList.correspondingStaticParameters = parameters;
       }
     }
-    if (propagatedElement != null) {
+    if (propagatedInvokeType != null) {
       List<ParameterElement> parameters =
-          _computeCorrespondingParameters(argumentList, propagatedElement);
+          _computeCorrespondingParameters(argumentList, propagatedInvokeType);
       if (parameters != null) {
         argumentList.correspondingPropagatedParameters = parameters;
       }
@@ -1336,48 +1322,44 @@
    * arguments, or `null` if no correspondence could be computed.
    */
   List<ParameterElement> _computeCorrespondingParameters(
-      ArgumentList argumentList, Element element) {
-    if (element is PropertyAccessorElement) {
-      //
-      // This is an invocation of the call method defined on the value returned
-      // by the getter.
-      //
-      FunctionType getterType = element.type;
-      if (getterType != null) {
-        DartType getterReturnType = getterType.returnType;
-        if (getterReturnType is InterfaceType) {
-          MethodElement callMethod = getterReturnType.lookUpMethod(
-              FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-          if (callMethod != null) {
-            return _resolveArgumentsToFunction(false, argumentList, callMethod);
-          }
-        } else if (getterReturnType is FunctionType) {
-          List<ParameterElement> parameters = getterReturnType.parameters;
-          return _resolveArgumentsToParameters(false, argumentList, parameters);
-        }
+      ArgumentList argumentList, DartType type) {
+    if (type is InterfaceType) {
+      MethodElement callMethod =
+          type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
+      if (callMethod != null) {
+        return _resolveArgumentsToFunction(false, argumentList, callMethod);
       }
-    } else if (element is ExecutableElement) {
-      return _resolveArgumentsToFunction(false, argumentList, element);
-    } else if (element is VariableElement) {
-      VariableElement variable = element;
-      DartType type = _promoteManager.getStaticType(variable);
-      if (type is FunctionType) {
-        FunctionType functionType = type;
-        List<ParameterElement> parameters = functionType.parameters;
-        return _resolveArgumentsToParameters(false, argumentList, parameters);
-      } else if (type is InterfaceType) {
-        // "call" invocation
-        MethodElement callMethod = type.lookUpMethod(
-            FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-        if (callMethod != null) {
-          List<ParameterElement> parameters = callMethod.parameters;
-          return _resolveArgumentsToParameters(false, argumentList, parameters);
-        }
-      }
+    } else if (type is FunctionType) {
+      return _resolveArgumentsToParameters(
+          false, argumentList, type.parameters);
     }
     return null;
   }
 
+  DartType _computeMethodInvokeType(MethodInvocation node, Element element) {
+    if (element == null) {
+      // TODO(jmesserly): should we return `dynamic` in this case?
+      // Otherwise we have to guard against `null` every time we use
+      // `staticInvokeType`.
+      // If we do return `dynamic` we need to be careful that this doesn't
+      // adversely affect propagatedType code path. But it shouldn't because
+      // we'll discard `dynamic` anyway (see _propagatedInvokeTypeIfBetter).
+      return null;
+    }
+
+    DartType invokeType;
+    if (element is PropertyAccessorElement) {
+      invokeType = element.returnType;
+    } else if (element is ExecutableElement) {
+      invokeType = element.type;
+    } else if (element is VariableElement) {
+      invokeType = _promoteManager.getStaticType(element);
+    }
+
+    return _resolveGenericMethod(
+        invokeType, node.typeArguments, node.methodName);
+  }
+
   /**
    * If the given [element] is a setter, return the getter associated with it.
    * Otherwise, return the element unchanged.
@@ -1758,6 +1740,24 @@
   }
 
   /**
+   * Determines if the [propagatedType] of the invoke is better (more specific)
+   * than the [staticType]. If so it will be returned, otherwise returns null.
+   */
+  // TODO(jmesserly): can we refactor Resolver.recordPropagatedTypeIfBetter to
+  // get some code sharing? Right now, this method is to support
+  // `staticInvokeType` and `propagatedInvokeType`, and the one in Resolver is
+  // for `staticType` and `propagatedType` on Expression.
+  DartType _propagatedInvokeTypeIfBetter(
+      DartType propagatedType, DartType staticType) {
+    if (propagatedType != null &&
+        (staticType == null || propagatedType.isMoreSpecificThan(staticType))) {
+      return propagatedType;
+    } else {
+      return null;
+    }
+  }
+
+  /**
    * Record that the given [node] is undefined, causing an error to be reported
    * if appropriate. The [declaringElement] is the element inside which no
    * declaration was found. If this element is a proxy, no error will be
@@ -1948,102 +1948,35 @@
    * Given an [argumentList] and the [executableElement] that will be invoked
    * using those argument, compute the list of parameters that correspond to the
    * list of arguments. An error will be reported if any of the arguments cannot
-   * be matched to a parameter. The flag [reportError] should be `true` if a
+   * be matched to a parameter. The flag [reportAsError] should be `true` if a
    * compile-time error should be reported; or `false` if a compile-time warning
    * should be reported. Return the parameters that correspond to the arguments,
    * or `null` if no correspondence could be computed.
    */
-  List<ParameterElement> _resolveArgumentsToFunction(bool reportError,
+  List<ParameterElement> _resolveArgumentsToFunction(bool reportAsError,
       ArgumentList argumentList, ExecutableElement executableElement) {
     if (executableElement == null) {
       return null;
     }
     List<ParameterElement> parameters = executableElement.parameters;
-    return _resolveArgumentsToParameters(reportError, argumentList, parameters);
+    return _resolveArgumentsToParameters(
+        reportAsError, argumentList, parameters);
   }
 
   /**
    * Given an [argumentList] and the [parameters] related to the element that
    * will be invoked using those arguments, compute the list of parameters that
    * correspond to the list of arguments. An error will be reported if any of
-   * the arguments cannot be matched to a parameter. The flag [reportError]
+   * the arguments cannot be matched to a parameter. The flag [reportAsError]
    * should be `true` if a compile-time error should be reported; or `false` if
    * a compile-time warning should be reported. Return the parameters that
    * correspond to the arguments.
    */
-  List<ParameterElement> _resolveArgumentsToParameters(bool reportError,
+  List<ParameterElement> _resolveArgumentsToParameters(bool reportAsError,
       ArgumentList argumentList, List<ParameterElement> parameters) {
-    List<ParameterElement> requiredParameters = new List<ParameterElement>();
-    List<ParameterElement> positionalParameters = new List<ParameterElement>();
-    HashMap<String, ParameterElement> namedParameters =
-        new HashMap<String, ParameterElement>();
-    for (ParameterElement parameter in parameters) {
-      ParameterKind kind = parameter.parameterKind;
-      if (kind == ParameterKind.REQUIRED) {
-        requiredParameters.add(parameter);
-      } else if (kind == ParameterKind.POSITIONAL) {
-        positionalParameters.add(parameter);
-      } else {
-        namedParameters[parameter.name] = parameter;
-      }
-    }
-    List<ParameterElement> unnamedParameters =
-        new List<ParameterElement>.from(requiredParameters);
-    unnamedParameters.addAll(positionalParameters);
-    int unnamedParameterCount = unnamedParameters.length;
-    int unnamedIndex = 0;
-    NodeList<Expression> arguments = argumentList.arguments;
-    int argumentCount = arguments.length;
-    List<ParameterElement> resolvedParameters =
-        new List<ParameterElement>(argumentCount);
-    int positionalArgumentCount = 0;
-    HashSet<String> usedNames = new HashSet<String>();
-    bool noBlankArguments = true;
-    for (int i = 0; i < argumentCount; i++) {
-      Expression argument = arguments[i];
-      if (argument is NamedExpression) {
-        SimpleIdentifier nameNode = argument.name.label;
-        String name = nameNode.name;
-        ParameterElement element = namedParameters[name];
-        if (element == null) {
-          ErrorCode errorCode = (reportError
-              ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
-              : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
-          _resolver.reportErrorForNode(errorCode, nameNode, [name]);
-        } else {
-          resolvedParameters[i] = element;
-          nameNode.staticElement = element;
-        }
-        if (!usedNames.add(name)) {
-          _resolver.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
-        }
-      } else {
-        if (argument is SimpleIdentifier && argument.name.isEmpty) {
-          noBlankArguments = false;
-        }
-        positionalArgumentCount++;
-        if (unnamedIndex < unnamedParameterCount) {
-          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
-        }
-      }
-    }
-    if (positionalArgumentCount < requiredParameters.length &&
-        noBlankArguments) {
-      ErrorCode errorCode = (reportError
-          ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
-          : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList,
-          [requiredParameters.length, positionalArgumentCount]);
-    } else if (positionalArgumentCount > unnamedParameterCount &&
-        noBlankArguments) {
-      ErrorCode errorCode = (reportError
-          ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
-          : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList,
-          [unnamedParameterCount, positionalArgumentCount]);
-    }
-    return resolvedParameters;
+    return ResolverVisitor.resolveArgumentsToParameters(
+        argumentList, parameters, _resolver.reportErrorForNode,
+        reportAsError: reportAsError);
   }
 
   void _resolveBinaryExpression(BinaryExpression node, String methodName) {
@@ -2148,6 +2081,36 @@
   }
 
   /**
+   * Check for a generic method & apply type arguments if any were passed.
+   */
+  DartType _resolveGenericMethod(
+      DartType invokeType, TypeArgumentList typeArguments, AstNode node) {
+    // TODO(jmesserly): support generic "call" methods on InterfaceType.
+    if (invokeType is FunctionType) {
+      FunctionType type = invokeType;
+      List<TypeParameterElement> parameters = type.typeFormals;
+
+      NodeList<TypeName> arguments = typeArguments?.arguments;
+      if (arguments != null && arguments.length != parameters.length) {
+        // Wrong number of type arguments. Ignore them
+        arguments = null;
+        _resolver.reportErrorForNode(
+            StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+            node,
+            [type, parameters.length, arguments?.length ?? 0]);
+      }
+      if (parameters.isNotEmpty) {
+        if (arguments == null) {
+          invokeType = _resolver.typeSystem.instantiateToBounds(type);
+        } else {
+          invokeType = type.instantiate(arguments.map((n) => n.type).toList());
+        }
+      }
+    }
+    return invokeType;
+  }
+
+  /**
    * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the
    * element being invoked. If the returned element is a method, then the method
    * will be invoked. If the returned element is a getter, the getter will be
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 0e762ee..4f8d664 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -675,7 +675,7 @@
   }
 
   /**
-   * Appendto the given [buffer] all sources with the given analysis [level],
+   * Append to the given [buffer] all sources with the given analysis [level],
    * prefixed with a label and a separator if [needsSeparator] is `true`.
    */
   bool _appendSources(
@@ -1047,6 +1047,11 @@
   bool get enableAssertMessage;
 
   /**
+   * Return `true` to if analysis is to enable async support.
+   */
+  bool get enableAsync;
+
+  /**
    * Return `true` to enable interface libraries (DEP 40).
    */
   bool get enableConditionalDirectives;
@@ -1155,6 +1160,11 @@
   bool enableAssertMessage = false;
 
   /**
+   * A flag indicating whether analysis is to enable async support.
+   */
+  bool enableAsync = true;
+
+  /**
    * A flag indicating whether interface libraries are to be supported (DEP 40).
    */
   bool enableConditionalDirectives = false;
@@ -1249,6 +1259,7 @@
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
     enableAssertMessage = options.enableAssertMessage;
+    enableAsync = options.enableAsync;
     enableStrictCallChecks = options.enableStrictCallChecks;
     enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
@@ -1769,7 +1780,7 @@
   /**
    * Initialize a newly created change object to represent a change to the
    * content of a source. The [contents] is the new contents of the source. The
-   * [offse] ist the offset into the current contents. The [oldLength] is the
+   * [offset] is the offset into the current contents. The [oldLength] is the
    * number of characters in the original contents that were replaced. The
    * [newLength] is the number of characters in the replacement text.
    */
@@ -2105,7 +2116,7 @@
   /**
    * The [PerformanceTag] for time spent in other phases of analysis.
    */
-  static PerformanceTag performAnaysis = new PerformanceTag('performAnaysis');
+  static PerformanceTag performAnalysis = new PerformanceTag('performAnalysis');
 
   /**
    * The [PerformanceTag] for time spent in the analysis task visitor after
@@ -2126,6 +2137,11 @@
    */
   static PerformanceTag incrementalAnalysis =
       new PerformanceTag('incrementalAnalysis');
+
+  /**
+   * The [PerformanceTag] for time spent in summaries support.
+   */
+  static PerformanceTag summary = new PerformanceTag('summary');
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 6e4638a..d644fcd 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1360,12 +1360,12 @@
     // TODO(jmesserly): this duplicates some code in isSubtypeOf and most of
     // _isGenericFunctionSubtypeOf. Ideally, we'd let TypeSystem produce
     // an error message once it's ready to "return false".
-    if (!overridingFT.boundTypeParameters.isEmpty) {
-      if (overriddenFT.boundTypeParameters.isEmpty) {
+    if (!overridingFT.typeFormals.isEmpty) {
+      if (overriddenFT.typeFormals.isEmpty) {
         overriddenFT = _typeSystem.instantiateToBounds(overriddenFT);
       } else {
-        List<TypeParameterElement> params1 = overridingFT.boundTypeParameters;
-        List<TypeParameterElement> params2 = overriddenFT.boundTypeParameters;
+        List<TypeParameterElement> params1 = overridingFT.typeFormals;
+        List<TypeParameterElement> params2 = overriddenFT.typeFormals;
         int count = params1.length;
         if (params2.length != count) {
           _errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 33510ed..de0306f 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2108,6 +2108,11 @@
   int _errorListenerLock = 0;
 
   /**
+   * A flag indicating whether the parser is to parse the async support.
+   */
+  bool _parseAsync = true;
+
+  /**
    * A flag indicating whether parser is to parse function bodies.
    */
   bool _parseFunctionBodies = true;
@@ -2188,6 +2193,13 @@
   }
 
   /**
+   * Set whether the parser is to parse the async support.
+   */
+  void set parseAsync(bool parseAsync) {
+    this._parseAsync = parseAsync;
+  }
+
+  /**
    * Set whether parser is to parse function bodies.
    */
   void set parseFunctionBodies(bool parseFunctionBodies) {
@@ -6087,6 +6099,9 @@
       Token star = null;
       if (_matchesString(ASYNC)) {
         keyword = getAndAdvance();
+        if (!_parseAsync) {
+          _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
+        }
         if (_matches(TokenType.STAR)) {
           star = getAndAdvance();
           _inGenerator = true;
@@ -6094,6 +6109,9 @@
         _inAsync = true;
       } else if (_matchesString(SYNC)) {
         keyword = getAndAdvance();
+        if (!_parseAsync) {
+          _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
+        }
         if (_matches(TokenType.STAR)) {
           star = getAndAdvance();
           _inGenerator = true;
@@ -9360,6 +9378,13 @@
       const ParserErrorCode('ASYNC_KEYWORD_USED_AS_IDENTIFIER',
           "The keywords 'async', 'await', and 'yield' may not be used as identifiers in an asynchronous or generator function.");
 
+  /**
+   * Some environments, such as Fletch, do not support async.
+   */
+  static const CompileTimeErrorCode ASYNC_NOT_SUPPORTED =
+      const CompileTimeErrorCode('ASYNC_NOT_SUPPORTED',
+          "Async and sync are not supported in this environment.");
+
   static const ParserErrorCode BREAK_OUTSIDE_OF_LOOP = const ParserErrorCode(
       'BREAK_OUTSIDE_OF_LOOP',
       "A break statement cannot be used outside of a loop or switch statement");
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 35616c6..0d856c8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2755,6 +2755,7 @@
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
+    _setDoc(element, node);
     _currentHolder.addType(element);
     className.staticElement = element;
     holder.validate();
@@ -3044,6 +3045,9 @@
           setter.variable = variable;
           setter.setter = true;
           setter.static = true;
+          if (node.returnType == null) {
+            setter.hasImplicitReturnType = true;
+          }
           variable.setter = setter;
           variable.final2 = false;
           _currentHolder.addAccessor(setter);
@@ -3096,10 +3100,6 @@
     if (_functionTypesToFix != null) {
       _functionTypesToFix.add(element);
     } else {
-      // TODO(jmesserly): for local functions inside of top-level generic
-      // functions, this is probably not right. The function type should be set
-      // after the enclosingElement is set, otherwise we won't be able to
-      // substitute those type parameters later.
       element.type = new FunctionTypeImpl(element);
     }
     element.hasImplicitReturnType = true;
@@ -3270,6 +3270,9 @@
           setter.abstract = node.isAbstract;
           setter.setter = true;
           setter.static = isStatic;
+          if (node.returnType == null) {
+            setter.hasImplicitReturnType = true;
+          }
           field.setter = setter;
           field.final2 = false;
           _currentHolder.addAccessor(setter);
@@ -8428,7 +8431,11 @@
       }
     } else {
       // TODO(leafp): Do downwards inference using the declared type
-      // of the binary operator.
+      // of the binary operator for other cases.
+      if (operatorType == TokenType.QUESTION_QUESTION) {
+        InferenceContext.setTypeFromNode(leftOperand, node);
+        InferenceContext.setTypeFromNode(rightOperand, node);
+      }
       safelyVisit(leftOperand);
       safelyVisit(rightOperand);
     }
@@ -9149,15 +9156,7 @@
     safelyVisit(node.typeArguments);
     node.accept(elementResolver);
     _inferFunctionExpressionsParametersTypes(node.argumentList);
-    Element methodElement = node.methodName.staticElement;
-    DartType contextType = null;
-    if (methodElement is PropertyAccessorElement && methodElement.isGetter) {
-      contextType = methodElement.returnType;
-    } else if (methodElement is VariableElement) {
-      contextType = methodElement.type;
-    } else if (methodElement is ExecutableElement) {
-      contextType = methodElement.type;
-    }
+    DartType contextType = node.staticInvokeType;
     if (contextType is FunctionType) {
       InferenceContext.setType(node.argumentList, contextType);
     }
@@ -9166,6 +9165,105 @@
     return null;
   }
 
+  /**
+   * Given an [argumentList] and the [parameters] related to the element that
+   * will be invoked using those arguments, compute the list of parameters that
+   * correspond to the list of arguments.
+   *
+   * An error will be reported to [onError] if any of the arguments cannot be
+   * matched to a parameter. onError can be null to ignore the error.
+   *
+   * The flag [reportAsError] should be `true` if a compile-time error should be
+   * reported; or `false` if a compile-time warning should be reported
+   *
+   * Returns the parameters that correspond to the arguments.
+   */
+  static List<ParameterElement> resolveArgumentsToParameters(
+      ArgumentList argumentList,
+      List<ParameterElement> parameters,
+      void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]),
+      {bool reportAsError: false}) {
+    List<ParameterElement> requiredParameters = new List<ParameterElement>();
+    List<ParameterElement> positionalParameters = new List<ParameterElement>();
+    HashMap<String, ParameterElement> namedParameters =
+        new HashMap<String, ParameterElement>();
+    for (ParameterElement parameter in parameters) {
+      ParameterKind kind = parameter.parameterKind;
+      if (kind == ParameterKind.REQUIRED) {
+        requiredParameters.add(parameter);
+      } else if (kind == ParameterKind.POSITIONAL) {
+        positionalParameters.add(parameter);
+      } else {
+        namedParameters[parameter.name] = parameter;
+      }
+    }
+    List<ParameterElement> unnamedParameters =
+        new List<ParameterElement>.from(requiredParameters);
+    unnamedParameters.addAll(positionalParameters);
+    int unnamedParameterCount = unnamedParameters.length;
+    int unnamedIndex = 0;
+    NodeList<Expression> arguments = argumentList.arguments;
+    int argumentCount = arguments.length;
+    List<ParameterElement> resolvedParameters =
+        new List<ParameterElement>(argumentCount);
+    int positionalArgumentCount = 0;
+    HashSet<String> usedNames = new HashSet<String>();
+    bool noBlankArguments = true;
+    for (int i = 0; i < argumentCount; i++) {
+      Expression argument = arguments[i];
+      if (argument is NamedExpression) {
+        SimpleIdentifier nameNode = argument.name.label;
+        String name = nameNode.name;
+        ParameterElement element = namedParameters[name];
+        if (element == null) {
+          ErrorCode errorCode = (reportAsError
+              ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
+              : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
+          if (onError != null) {
+            onError(errorCode, nameNode, [name]);
+          }
+        } else {
+          resolvedParameters[i] = element;
+          nameNode.staticElement = element;
+        }
+        if (!usedNames.add(name)) {
+          if (onError != null) {
+            onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode,
+                [name]);
+          }
+        }
+      } else {
+        if (argument is SimpleIdentifier && argument.name.isEmpty) {
+          noBlankArguments = false;
+        }
+        positionalArgumentCount++;
+        if (unnamedIndex < unnamedParameterCount) {
+          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
+        }
+      }
+    }
+    if (positionalArgumentCount < requiredParameters.length &&
+        noBlankArguments) {
+      ErrorCode errorCode = (reportAsError
+          ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
+          : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
+      if (onError != null) {
+        onError(errorCode, argumentList,
+            [requiredParameters.length, positionalArgumentCount]);
+      }
+    } else if (positionalArgumentCount > unnamedParameterCount &&
+        noBlankArguments) {
+      ErrorCode errorCode = (reportAsError
+          ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
+          : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
+      if (onError != null) {
+        onError(errorCode, argumentList,
+            [unnamedParameterCount, positionalArgumentCount]);
+      }
+    }
+    return resolvedParameters;
+  }
+
   @override
   Object visitNamedExpression(NamedExpression node) {
     InferenceContext.setType(node.expression, InferenceContext.getType(node));
@@ -11758,6 +11856,11 @@
   bool _hasReferenceToSuper = false;
 
   /**
+   * True if we're analyzing in strong mode.
+   */
+  bool _strongMode;
+
+  /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
    *
    * [definingLibrary] is the element for the library containing the node being
@@ -11779,6 +11882,7 @@
             nameScope: nameScope) {
     _dynamicType = typeProvider.dynamicType;
     _undefinedType = typeProvider.undefinedType;
+    _strongMode = definingLibrary.context.analysisOptions.strongMode;
   }
 
   @override
@@ -12019,6 +12123,7 @@
     }
     element.returnType = _computeReturnType(node.returnType);
     element.type = new FunctionTypeImpl(element);
+    _inferSetterReturnType(element);
     return null;
   }
 
@@ -12067,6 +12172,7 @@
     }
     element.returnType = _computeReturnType(node.returnType);
     element.type = new FunctionTypeImpl(element);
+    _inferSetterReturnType(element);
     if (element is PropertyAccessorElement) {
       PropertyAccessorElement accessor = element as PropertyAccessorElement;
       PropertyInducingElementImpl variable =
@@ -12556,7 +12662,7 @@
     if (type is InterfaceType) {
       return type.typeArguments;
     } else if (type is FunctionType) {
-      return TypeParameterTypeImpl.getTypes(type.boundTypeParameters);
+      return TypeParameterTypeImpl.getTypes(type.typeFormals);
     }
     return DartType.EMPTY_LIST;
   }
@@ -12595,7 +12701,25 @@
     return type;
   }
 
+  /**
+   * In strong mode we infer "void" as the setter return type (as void is the
+   * only legal return type for a setter). This allows us to give better
+   * errors later if an invalid type is returned.
+   */
+  void _inferSetterReturnType(ExecutableElementImpl element) {
+    if (_strongMode &&
+        element is PropertyAccessorElementImpl &&
+        element.isSetter &&
+        element.hasImplicitReturnType) {
+      element.returnType = VoidTypeImpl.instance;
+    }
+  }
+
   DartType _instantiateType(DartType type, List<DartType> typeArguments) {
+    // TODO(jmesserly): this should use TypeSystem.instantiateToBounds,
+    // from calling methods when they know they're just trying to fill in
+    // "dynamic" for the case of missing type arguments.
+
     if (type is InterfaceTypeImpl) {
       return type.substitute4(typeArguments);
     } else if (type is FunctionTypeImpl) {
@@ -12842,7 +12966,9 @@
     functionElement.shareParameters(parameters);
     functionElement.returnType = _computeReturnType(returnType);
     functionElement.enclosingElement = element;
+    functionElement.shareTypeParameters(element.typeParameters);
     element.type = new FunctionTypeImpl(functionElement);
+    functionElement.type = element.type;
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 1fc4b33..863a3d4 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -4,6 +4,7 @@
 
 library analyzer.src.generated.sdk_io;
 
+import 'dart:collection';
 import 'dart:io';
 
 import 'package:analyzer/src/context/context.dart';
@@ -201,6 +202,11 @@
   JavaFile _sdkDirectory;
 
   /**
+   * The directory within the SDK directory that contains the libraries.
+   */
+  JavaFile _libraryDirectory;
+
+  /**
    * The revision number of this SDK, or `"0"` if the revision number cannot be
    * discovered.
    */
@@ -232,6 +238,11 @@
   LibraryMap _libraryMap;
 
   /**
+   * The mapping from Dart URI's to the corresponding sources.
+   */
+  Map<String, Source> _uriToSourceMap = new HashMap<String, Source>();
+
+  /**
    * Initialize a newly created SDK to represent the Dart SDK installed in the
    * [sdkDirectory]. The flag [useDart2jsPaths] is `true` if the dart2js path
    * should be used when it is available
@@ -333,8 +344,13 @@
   /**
    * Return the directory within the SDK directory that contains the libraries.
    */
-  JavaFile get libraryDirectory =>
-      new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME);
+  JavaFile get libraryDirectory {
+    if (_libraryDirectory == null) {
+      _libraryDirectory =
+          new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME);
+    }
+    return _libraryDirectory;
+  }
 
   /**
    * Return the file containing the Pub executable, or `null` if it does not exist.
@@ -514,6 +530,35 @@
 
   @override
   Source mapDartUri(String dartUri) {
+    Source source = _uriToSourceMap[dartUri];
+    if (source == null) {
+      source = _mapDartUri(dartUri);
+      _uriToSourceMap[dartUri] = source;
+    }
+    return source;
+  }
+
+  /**
+   * Return the [SdkBundle] for this SDK, if it exists, or `null` otherwise.
+   */
+  SdkBundle _getSummarySdkBundle() {
+    String rootPath = directory.getAbsolutePath();
+    String path = pathos.join(rootPath, 'lib', '_internal', 'analysis_summary');
+    try {
+      File file = new File(path);
+      if (file.existsSync()) {
+        List<int> bytes = file.readAsBytesSync();
+        return new SdkBundle.fromBuffer(bytes);
+      }
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          'Failed to load SDK analysis summary from $path',
+          new CaughtException(exception, stackTrace));
+    }
+    return null;
+  }
+
+  FileBasedSource _mapDartUri(String dartUri) {
     String libraryName;
     String relativePath;
     int index = dartUri.indexOf('/');
@@ -541,26 +586,6 @@
   }
 
   /**
-   * Return the [SdkBundle] for this SDK, if it exists, or `null` otherwise.
-   */
-  SdkBundle _getSummarySdkBundle() {
-    String rootPath = directory.getAbsolutePath();
-    String path = pathos.join(rootPath, 'lib', '_internal', 'analysis_summary');
-    try {
-      File file = new File(path);
-      if (file.existsSync()) {
-        List<int> bytes = file.readAsBytesSync();
-        return new SdkBundle.fromBuffer(bytes);
-      }
-    } catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logError(
-          'Failed to load SDK analysis summary from $path',
-          new CaughtException(exception, stackTrace));
-    }
-    return null;
-  }
-
-  /**
    * Return the given [file] if it exists and is executable, or `null` if it
    * does not exist or is not executable.
    */
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 3c25f11..950f36e0 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -834,8 +834,13 @@
 
     // Check .packages and update target and actual URIs as appropriate.
     if (_packages != null && containedUri.scheme == 'package') {
-      Uri packageUri =
-          _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
+      Uri packageUri = null;
+      try {
+        packageUri =
+            _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
+      } on ArgumentError {
+        // Fall through to try resolvers.
+      }
 
       if (packageUri != null) {
         // Ensure scheme is set.
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 106ff7a..28f42f7 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -330,7 +330,7 @@
   @override
   Object visitBinaryExpression(BinaryExpression node) {
     if (node.operator.type == TokenType.QUESTION_QUESTION) {
-      // Evaluation of an if-null expresion e of the form e1 ?? e2 is
+      // Evaluation of an if-null expression e of the form e1 ?? e2 is
       // equivalent to the evaluation of the expression
       // ((x) => x == null ? e2 : x)(e1).  The static type of e is the least
       // upper bound of the static type of e1 and the static type of e2.
@@ -413,9 +413,11 @@
     FunctionExpression function = node.functionExpression;
     ExecutableElementImpl functionElement =
         node.element as ExecutableElementImpl;
-    functionElement.returnType =
-        _computeStaticReturnTypeOfFunctionDeclaration(node);
     if (node.parent is FunctionDeclarationStatement) {
+      // TypeResolverVisitor sets the return type for top-level functions, so
+      // we only need to handle local functions.
+      functionElement.returnType =
+          _computeStaticReturnTypeOfFunctionDeclaration(node);
       _recordPropagatedTypeOfFunction(functionElement, function.body);
     }
     _recordStaticType(function, functionElement.type);
@@ -493,15 +495,9 @@
    */
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    DartType functionStaticType = _getStaticType(node.function);
-    DartType staticType;
-    if (functionStaticType is FunctionType) {
-      staticType = functionStaticType.returnType;
-    } else {
-      staticType = _dynamicType;
-    }
+    DartType staticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticType);
-    DartType functionPropagatedType = node.function.propagatedType;
+    DartType functionPropagatedType = node.propagatedInvokeType;
     if (functionPropagatedType is FunctionType) {
       DartType propagatedType = functionPropagatedType.returnType;
       _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
@@ -726,7 +722,7 @@
       _resolver.recordPropagatedTypeIfBetter(methodNameNode, propagatedType);
     }
     // Record static return type of the static element.
-    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
+    DartType staticStaticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticStaticType);
     // Record propagated return type of the static element.
     DartType staticPropagatedType =
@@ -736,12 +732,6 @@
     bool needPropagatedType = true;
     String methodName = methodNameNode.name;
     if (_strongMode) {
-      // TODO(leafp): Revisit this.  It's here to associate a type with the
-      // method name, which is important to the DDC backend (but apparently
-      // no-one else).  Not sure that there's a problem having this here, but
-      // it's a little ad hoc.
-      visitSimpleIdentifier(methodNameNode);
-
       _inferMethodInvocation(node);
     }
     if (methodName == "then") {
@@ -1438,38 +1428,28 @@
       //
       FunctionType propertyType = element.type;
       if (propertyType != null) {
-        DartType returnType = propertyType.returnType;
-        if (returnType.isDartCoreFunction) {
-          return _dynamicType;
-        } else if (returnType is InterfaceType) {
-          MethodElement callMethod = returnType.lookUpMethod(
-              FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
-          if (callMethod != null) {
-            return callMethod.type.returnType;
-          }
-        } else if (returnType is FunctionType) {
-          DartType innerReturnType = returnType.returnType;
-          if (innerReturnType != null) {
-            return innerReturnType;
-          }
-        }
-        if (returnType != null) {
-          return returnType;
-        }
+        return _computeInvokeReturnType(propertyType.returnType);
       }
     } else if (element is ExecutableElement) {
-      FunctionType type = element.type;
-      if (type != null) {
-        // TODO(brianwilkerson) Figure out the conditions under which the type
-        // is null.
-        return type.returnType;
-      }
+      return _computeInvokeReturnType(element.type);
     } else if (element is VariableElement) {
-      VariableElement variable = element;
-      DartType variableType = _promoteManager.getStaticType(variable);
-      if (variableType is FunctionType) {
-        return variableType.returnType;
-      }
+      DartType variableType = _promoteManager.getStaticType(element);
+      return _computeInvokeReturnType(variableType);
+    }
+    return _dynamicType;
+  }
+
+  /**
+   * Compute the return type of the method or function represented by the given
+   * type that is being invoked.
+   */
+  DartType _computeInvokeReturnType(DartType type) {
+    if (type is InterfaceType) {
+      MethodElement callMethod = type.lookUpMethod(
+          FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
+      return callMethod?.type?.returnType ?? _dynamicType;
+    } else if (type is FunctionType) {
+      return type.returnType ?? _dynamicType;
     }
     return _dynamicType;
   }
@@ -1823,58 +1803,41 @@
    */
   bool _inferMethodInvocationGeneric(MethodInvocation node) {
     Element element = node.methodName.staticElement;
-    DartType fnType = node.methodName.staticType;
+    DartType invokeType = node.staticInvokeType;
+
     TypeSystem ts = _typeSystem;
     if (node.typeArguments == null &&
         element is ExecutableElement &&
-        fnType is FunctionTypeImpl &&
         ts is StrongTypeSystemImpl) {
-      FunctionTypeImpl genericFunction = fnType.originalFunction;
-      if (element is PropertyAccessorElement) {
-        genericFunction = element.type.returnType;
-      }
-      if (genericFunction.boundTypeParameters.isEmpty) {
-        return false;
-      }
-      for (DartType typeArg in fnType.instantiatedTypeArguments) {
-        if (!typeArg.isDynamic) {
-          return false;
-        }
-      }
+      FunctionType fnType = element.type;
+      if (fnType.typeFormals.isNotEmpty &&
+          ts.instantiateToBounds(fnType) == invokeType) {
+        // Get the parameters that correspond to the uninstantiated generic.
+        List<ParameterElement> genericParameters =
+            ResolverVisitor.resolveArgumentsToParameters(
+                node.argumentList, fnType.parameters, null);
 
-      List<ParameterElement> genericParameters = genericFunction.parameters;
-      List<DartType> argTypes = new List<DartType>();
-      List<DartType> paramTypes = new List<DartType>();
-      for (Expression arg in node.argumentList.arguments) {
-        // We may have too many (or too few) arguments.  Only use arguments
-        // which have been matched up with a static parameter.
-        ParameterElement p = arg.staticParameterElement;
-        if (p != null) {
-          int i = element.parameters.indexOf(p);
-          argTypes.add(arg.staticType);
-          paramTypes.add(genericParameters[i].type);
+        int length = genericParameters.length;
+        List<DartType> argTypes = new List<DartType>(length);
+        List<DartType> paramTypes = new List<DartType>(length);
+        for (int i = 0; i < length; i++) {
+          argTypes[i] = node.argumentList.arguments[i].staticType;
+          paramTypes[i] = genericParameters[i].type;
         }
-      }
 
-      FunctionType inferred = ts.inferCallFromArguments(
-          _typeProvider, genericFunction, paramTypes, argTypes);
-      if (inferred != fnType) {
-        // TODO(jmesserly): we need to fix up the parameter elements based on
-        // inferred method.
-        List<ParameterElement> inferredParameters = inferred.parameters;
-        List<ParameterElement> correspondingParams =
-            new List<ParameterElement>();
-        for (Expression arg in node.argumentList.arguments) {
-          ParameterElement p = arg.staticParameterElement;
-          if (p != null) {
-            int i = element.parameters.indexOf(p);
-            correspondingParams.add(inferredParameters[i]);
-          }
+        FunctionType inferred = ts.inferCallFromArguments(
+            _typeProvider, fnType, paramTypes, argTypes);
+
+        if (inferred != fnType) {
+          // Fix up the parameter elements based on inferred method.
+          List<ParameterElement> inferredParameters =
+              ResolverVisitor.resolveArgumentsToParameters(
+                  node.argumentList, inferred.parameters, null);
+          node.argumentList.correspondingStaticParameters = inferredParameters;
+          node.staticInvokeType = inferred;
+          _recordStaticType(node, inferred.returnType);
+          return true;
         }
-        node.argumentList.correspondingStaticParameters = correspondingParams;
-        _recordStaticType(node.methodName, inferred);
-        _recordStaticType(node, inferred.returnType);
-        return true;
       }
     }
     return false;
@@ -1934,7 +1897,7 @@
         inferredType.parameters.isEmpty &&
         node.argumentList.arguments.isEmpty &&
         _typeProvider.nonSubtypableTypes.contains(inferredType.returnType)) {
-      _recordStaticType(node.methodName, inferredType);
+      node.staticInvokeType = inferredType;
       _recordStaticType(node, inferredType.returnType);
       return true;
     }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 8e813e3..911dfa9 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -69,12 +69,12 @@
       FunctionTypeImpl fnType,
       List<DartType> correspondingParameterTypes,
       List<DartType> argumentTypes) {
-    if (fnType.boundTypeParameters.isEmpty) {
+    if (fnType.typeFormals.isEmpty) {
       return fnType;
     }
 
     List<TypeParameterType> fnTypeParams =
-        TypeParameterTypeImpl.getTypes(fnType.boundTypeParameters);
+        TypeParameterTypeImpl.getTypes(fnType.typeFormals);
 
     // Create a TypeSystem that will allow certain type parameters to be
     // inferred. It will optimistically assume these type parameters can be
@@ -158,7 +158,7 @@
    * Ii in all of the remaining bounds.
    */
   DartType instantiateToBounds(FunctionType function) {
-    int count = function.boundTypeParameters.length;
+    int count = function.typeFormals.length;
     if (count == 0) {
       return function;
     }
@@ -167,7 +167,7 @@
     List<DartType> substituted = new List<DartType>();
     List<DartType> variables = new List<DartType>();
     for (int i = 0; i < count; i++) {
-      TypeParameterElement param = function.boundTypeParameters[i];
+      TypeParameterElement param = function.typeFormals[i];
       DartType bound = param.bound ?? DynamicTypeImpl.instance;
       DartType variable = param.type;
       // For each Ti extends Bi, first compute Ii by replacing
@@ -287,8 +287,8 @@
    */
   bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
       {bool fuzzyArrows: true}) {
-    if (!f1.boundTypeParameters.isEmpty) {
-      if (f2.boundTypeParameters.isEmpty) {
+    if (!f1.typeFormals.isEmpty) {
+      if (f2.typeFormals.isEmpty) {
         f1 = instantiateToBounds(f1);
         return _isFunctionSubtypeOf(f1, f2);
       } else {
@@ -383,8 +383,8 @@
    */
   bool _isGenericFunctionSubtypeOf(FunctionType f1, FunctionType f2,
       {bool fuzzyArrows: true}) {
-    List<TypeParameterElement> params1 = f1.boundTypeParameters;
-    List<TypeParameterElement> params2 = f2.boundTypeParameters;
+    List<TypeParameterElement> params1 = f1.typeFormals;
+    List<TypeParameterElement> params2 = f2.typeFormals;
     int count = params1.length;
     if (params2.length != count) {
       return false;
@@ -689,7 +689,7 @@
    * Instantiate the function type using `dynamic` for all generic parameters.
    */
   FunctionType instantiateToBounds(FunctionType function) {
-    int count = function.boundTypeParameters.length;
+    int count = function.typeFormals.length;
     if (count == 0) {
       return function;
     }
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index 004433c..1adc883 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -8,6 +8,12 @@
 import 'dart:developer' show UserTag;
 
 /**
+ * Test if the given [value] is `false` or the string "false" (case-insensitive).
+ */
+bool isFalse(Object value) =>
+    value is bool ? !value : toLowerCase(value) == 'false';
+
+/**
  * Test if the given [value] is `true` or the string "true" (case-insensitive).
  */
 bool isTrue(Object value) =>
diff --git a/pkg/analyzer/lib/src/summary/base.dart b/pkg/analyzer/lib/src/summary/base.dart
index 0002dc9..a04476b 100644
--- a/pkg/analyzer/lib/src/summary/base.dart
+++ b/pkg/analyzer/lib/src/summary/base.dart
@@ -8,20 +8,6 @@
 library analyzer.src.summary.base;
 
 /**
- * Instances of this class encapsulate the necessary state to keep track of a
- * serialized summary that is in the process of being built.
- *
- * This class is intended to be passed to the constructors of the summary
- * Builder classes.
- */
-class BuilderContext {
-  // Note: at the moment this is a placeholder class since the current
-  // serialization format (JSON) doesn't require any state tracking.  If/when
-  // we switch to a serialization format that requires state tracking, the
-  // state will be stored here.
-}
-
-/**
  * Instances of this class represent data that has been read from a summary.
  */
 abstract class SummaryClass {
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
new file mode 100644
index 0000000..3c7de13
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -0,0 +1,631 @@
+// Copyright (c) 2016, 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 analyzer.src.summary.flat_buffers;
+
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:math';
+import 'dart:typed_data';
+
+/**
+ * The reader of booleans.
+ */
+class BoolReader extends Reader<bool> {
+  const BoolReader() : super();
+
+  @override
+  int get size => 1;
+
+  @override
+  bool read(BufferPointer bp) => bp._getInt8() != 0;
+}
+
+/**
+ * A pointer to some data.
+ */
+class BufferPointer {
+  final ByteData _buffer;
+  final int _offset;
+
+  factory BufferPointer.fromBytes(List<int> byteList, [int offset = 0]) {
+    Uint8List uint8List = _asUint8List(byteList);
+    ByteData buf = new ByteData.view(uint8List.buffer);
+    return new BufferPointer._(buf, uint8List.offsetInBytes + offset);
+  }
+
+  BufferPointer._(this._buffer, this._offset);
+
+  BufferPointer derefObject() {
+    int uOffset = _getUint32();
+    return _advance(uOffset);
+  }
+
+  @override
+  String toString() => _offset.toString();
+
+  BufferPointer _advance(int delta) {
+    return new BufferPointer._(_buffer, _offset + delta);
+  }
+
+  int _getInt32([int delta = 0]) =>
+      _buffer.getInt32(_offset + delta, Endianness.LITTLE_ENDIAN);
+
+  int _getInt8([int delta = 0]) => _buffer.getInt8(_offset + delta);
+
+  int _getUint16([int delta = 0]) =>
+      _buffer.getUint16(_offset + delta, Endianness.LITTLE_ENDIAN);
+
+  int _getUint32([int delta = 0]) =>
+      _buffer.getUint32(_offset + delta, Endianness.LITTLE_ENDIAN);
+
+  /**
+   * If the [byteList] is already a [Uint8List] return it.
+   * Otherwise return a [Uint8List] copy of the [byteList].
+   */
+  static Uint8List _asUint8List(List<int> byteList) {
+    if (byteList is Uint8List) {
+      return byteList;
+    } else {
+      return new Uint8List.fromList(byteList);
+    }
+  }
+}
+
+/**
+ * Class that helps building flat buffers.
+ */
+class Builder {
+  final int initialSize;
+
+  /**
+   * The list of existing VTable(s).
+   */
+  final List<_VTable> _vTables = <_VTable>[];
+
+  ByteData _buf;
+
+  /**
+   * The maximum alignment that has been seen so far.  If [_buf] has to be
+   * reallocated in the future (to insert room at its start for more bytes) the
+   * reallocation will need to be a multiple of this many bytes.
+   */
+  int _maxAlign;
+
+  /**
+   * The number of bytes that have been written to the buffer so far.  The
+   * most recently written byte is this many bytes from the end of [_buf].
+   */
+  int _tail;
+
+  /**
+   * The location of the end of the current table, measured in bytes from the
+   * end of [_buf], or `null` if a table is not currently being built.
+   */
+  int _currentTableEndTail;
+
+  _VTable _currentVTable;
+
+  Builder({this.initialSize: 1024}) {
+    reset();
+  }
+
+  /**
+   * Add the [field] with the given boolean [value].  The field is not added if
+   * the [value] is equal to [def].  Booleans are stored as 8-bit fields with
+   * `0` for `false` and `1` for `true`.
+   */
+  void addBool(int field, bool value, [bool def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 1;
+      _prepare(size, 1);
+      _trackField(field);
+      _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0);
+    }
+  }
+
+  /**
+   * Add the [field] with the given 32-bit signed integer [value].  The field is
+   * not added if the [value] is equal to [def].
+   */
+  void addInt32(int field, int value, [int def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 4;
+      _prepare(size, 1);
+      _trackField(field);
+      _setInt32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /**
+   * Add the [field] with the given 8-bit signed integer [value].  The field is
+   * not added if the [value] is equal to [def].
+   */
+  void addInt8(int field, int value, [int def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 1;
+      _prepare(size, 1);
+      _trackField(field);
+      _buf.setInt8(_buf.lengthInBytes - _tail, value);
+    }
+  }
+
+  /**
+   * Add the [field] referencing an object with the given [offset].
+   */
+  void addOffset(int field, Offset offset) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (offset != null) {
+      _prepare(4, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, _tail - offset._tail);
+    }
+  }
+
+  /**
+   * End the current table and return its offset.
+   */
+  Offset endTable() {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before ending it.');
+    }
+    // Prepare the size of the current table.
+    _currentVTable.tableSize = _tail - _currentTableEndTail;
+    // Prepare for writing the VTable.
+    _prepare(4, 1);
+    int tableTail = _tail;
+    // Prepare the VTable to use for the current table.
+    int vTableTail;
+    {
+      _currentVTable.computeFieldOffsets(tableTail);
+      // Try to find an existing compatible VTable.
+      for (_VTable vTable in _vTables) {
+        if (_currentVTable.canUseExistingVTable(vTable)) {
+          vTableTail = vTable.tail;
+        }
+      }
+      // Write a new VTable.
+      if (vTableTail == null) {
+        _prepare(2, _currentVTable.numOfUint16);
+        vTableTail = _tail;
+        _currentVTable.tail = vTableTail;
+        _currentVTable.output(_buf, _buf.lengthInBytes - _tail);
+        _vTables.add(_currentVTable);
+      }
+    }
+    // Set the VTable offset.
+    _setInt32AtTail(_buf, tableTail, vTableTail - tableTail);
+    // Done with this table.
+    _currentVTable = null;
+    return new Offset(tableTail);
+  }
+
+  /**
+   * Finish off the creation of the buffer.  The given [offset] is used as the
+   * root object offset, and usually references directly or indirectly every
+   * written object.
+   */
+  Uint8List finish(Offset offset) {
+    _prepare(max(4, _maxAlign), 1);
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    _setUint32AtTail(_buf, alignedTail, alignedTail - offset._tail);
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  Uint8List lowFinish() {
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  void lowReset() {
+    _buf = new ByteData(initialSize);
+    _maxAlign = 1;
+    _tail = 0;
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  void lowWriteUint32(int value) {
+    _prepare(4, 1);
+    _setUint32AtTail(_buf, _tail, value);
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  void lowWriteUint8(int value) {
+    _prepare(1, 1);
+    _buf.setUint8(_buf.lengthInBytes - _tail, value);
+  }
+
+  /**
+   * Reset the builder and make it ready for filling a new buffer.
+   */
+  void reset() {
+    _buf = new ByteData(initialSize);
+    _maxAlign = 1;
+    _tail = 0;
+    _currentVTable = null;
+  }
+
+  /**
+   * Start a new table.  Must be finished with [endTable] invocation.
+   */
+  void startTable() {
+    if (_currentVTable != null) {
+      throw new StateError('Inline tables are not supported.');
+    }
+    _currentVTable = new _VTable();
+    _currentTableEndTail = _tail;
+  }
+
+  /**
+   * Write the given list of [values].
+   */
+  Offset writeList(List<Offset> values) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    _prepare(4, 1 + values.length);
+    Offset result = new Offset(_tail);
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= 4;
+    for (Offset value in values) {
+      _setUint32AtTail(_buf, tail, tail - value._tail);
+      tail -= 4;
+    }
+    return result;
+  }
+
+  /**
+   * Write the given list of signed 32-bit integer [values].
+   */
+  Offset writeListInt32(List<int> values) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    _prepare(4, 1 + values.length);
+    Offset result = new Offset(_tail);
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= 4;
+    for (int value in values) {
+      _setInt32AtTail(_buf, tail, value);
+      tail -= 4;
+    }
+    return result;
+  }
+
+  /**
+   * Write the given string [value] and return its [Offset], or `null` if
+   * the [value] is equal to [def].
+   */
+  Offset<String> writeString(String value, [String def]) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    if (value != def) {
+      // TODO(scheglov) optimize for ASCII strings
+      List<int> bytes = UTF8.encode(value);
+      int length = bytes.length;
+      _prepare(4, 1, additionalBytes: length);
+      Offset<String> result = new Offset(_tail);
+      _setUint32AtTail(_buf, _tail, length);
+      int offset = _buf.lengthInBytes - _tail + 4;
+      for (int i = 0; i < length; i++) {
+        _buf.setUint8(offset++, bytes[i]);
+      }
+      return result;
+    }
+    return null;
+  }
+
+  /**
+   * Prepare for writing the given [count] of scalars of the given [size].
+   * Additionally allocate the specified [additionalBytes]. Update the current
+   * tail pointer to point at the allocated space.
+   */
+  void _prepare(int size, int count, {int additionalBytes: 0}) {
+    // Update the alignment.
+    if (_maxAlign < size) {
+      _maxAlign = size;
+    }
+    // Prepare amount of required space.
+    int dataSize = size * count + additionalBytes;
+    int alignDelta = (-(_tail + dataSize)) % size;
+    int bufSize = alignDelta + dataSize;
+    // Ensure that we have the required amount of space.
+    {
+      int oldCapacity = _buf.lengthInBytes;
+      if (_tail + bufSize > oldCapacity) {
+        int desiredNewCapacity = (oldCapacity + bufSize) * 2;
+        int deltaCapacity = desiredNewCapacity - oldCapacity;
+        deltaCapacity += (-deltaCapacity) % _maxAlign;
+        int newCapacity = oldCapacity + deltaCapacity;
+        ByteData newBuf = new ByteData(newCapacity);
+        newBuf.buffer
+            .asUint8List()
+            .setAll(deltaCapacity, _buf.buffer.asUint8List());
+        _buf = newBuf;
+      }
+    }
+    // Update the tail pointer.
+    _tail += bufSize;
+  }
+
+  /**
+   * Record the offset of the given [field].
+   */
+  void _trackField(int field) {
+    _currentVTable.addField(field, _tail);
+  }
+
+  static void _setInt32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+  }
+
+  static void _setUint32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+  }
+}
+
+/**
+ * The reader of 32-bit signed integers.
+ */
+class Int32Reader extends Reader<int> {
+  const Int32Reader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  int read(BufferPointer bp) => bp._getInt32();
+}
+
+/**
+ * The reader of 8-bit signed integers.
+ */
+class Int8Reader extends Reader<int> {
+  const Int8Reader() : super();
+
+  @override
+  int get size => 1;
+
+  @override
+  int read(BufferPointer bp) => bp._getInt8();
+}
+
+/**
+ * The reader of lists of objects.
+ *
+ * The returned unmodifiable lists lazily read objects on access.
+ */
+class ListReader<E> extends Reader<List<E>> {
+  final Reader<E> _elementReader;
+
+  const ListReader(this._elementReader);
+
+  @override
+  int get size => 4;
+
+  @override
+  List<E> read(BufferPointer bp) =>
+      new _FbList<E>(_elementReader, bp.derefObject());
+}
+
+/**
+ * The offset from the end of the buffer to a serialized object of the type [T].
+ */
+class Offset<T> {
+  final int _tail;
+
+  Offset(this._tail);
+}
+
+/**
+ * Object that can read a value at a [BufferPointer].
+ */
+abstract class Reader<T> {
+  const Reader();
+
+  /**
+   * The size of the value in bytes.
+   */
+  int get size;
+
+  /**
+   * Read the value at the given pointer.
+   */
+  T read(BufferPointer bp);
+
+  /**
+   * Read the value of the given [field] in the given [object].
+   */
+  T vTableGet(BufferPointer object, int field, [T defaultValue]) {
+    int vTableSOffset = object._getInt32();
+    BufferPointer vTable = object._advance(-vTableSOffset);
+    int vTableSize = vTable._getUint16();
+    int vTableFieldOffset = (1 + 1 + field) * 2;
+    if (vTableFieldOffset < vTableSize) {
+      int fieldOffsetInObject = vTable._getUint16(vTableFieldOffset);
+      if (fieldOffsetInObject != 0) {
+        BufferPointer fieldPointer = object._advance(fieldOffsetInObject);
+        return read(fieldPointer);
+      }
+    }
+    return defaultValue;
+  }
+}
+
+/**
+ * The reader of string values.
+ */
+class StringReader extends Reader<String> {
+  const StringReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  String read(BufferPointer ref) {
+    BufferPointer object = ref.derefObject();
+    int length = object._getUint32();
+    return UTF8
+        .decode(ref._buffer.buffer.asUint8List(object._offset + 4, length));
+  }
+}
+
+/**
+ * An abstract reader for tables.
+ */
+abstract class TableReader<T> extends Reader<T> {
+  const TableReader();
+
+  @override
+  int get size => 4;
+
+  /**
+   * Return the object at [bp].
+   */
+  T createObject(BufferPointer bp);
+
+  @override
+  T read(BufferPointer bp) {
+    bp = bp.derefObject();
+    return createObject(bp);
+  }
+}
+
+class _FbList<E> extends Object with ListMixin<E> implements List<E> {
+  final Reader<E> elementReader;
+  final BufferPointer bp;
+
+  int _length;
+  List<E> _items;
+
+  _FbList(this.elementReader, this.bp);
+
+  @override
+  int get length {
+    _length ??= bp._getUint32();
+    return _length;
+  }
+
+  @override
+  void set length(int i) =>
+      throw new StateError('Attempt to modify immutable list');
+
+  @override
+  E operator [](int i) {
+    _items ??= new List<E>(length);
+    E item = _items[i];
+    if (item == null) {
+      BufferPointer ref = bp._advance(4 + elementReader.size * i);
+      item = elementReader.read(ref);
+      _items[i] = item;
+    }
+    return item;
+  }
+
+  @override
+  void operator []=(int i, E e) =>
+      throw new StateError('Attempt to modify immutable list');
+}
+
+/**
+ * Class that describes the structure of a table.
+ */
+class _VTable {
+  final List<int> fieldTails = <int>[];
+  final List<int> fieldOffsets = <int>[];
+
+  /**
+   * The size of the table that uses this VTable.
+   */
+  int tableSize;
+
+  /**
+   * The tail of this VTable.  It is used to share the same VTable between
+   * multiple tables of identical structure.
+   */
+  int tail;
+
+  int get numOfUint16 => 1 + 1 + fieldTails.length;
+
+  void addField(int field, int offset) {
+    while (fieldTails.length <= field) {
+      fieldTails.add(null);
+    }
+    fieldTails[field] = offset;
+  }
+
+  /**
+   * Return `true` if the [existing] VTable can be used instead of this.
+   */
+  bool canUseExistingVTable(_VTable existing) {
+    assert(tail == null);
+    assert(existing.tail != null);
+    if (tableSize == existing.tableSize &&
+        fieldOffsets.length == existing.fieldOffsets.length) {
+      for (int i = 0; i < fieldOffsets.length; i++) {
+        if (fieldOffsets[i] != existing.fieldOffsets[i]) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Fill the [fieldOffsets] field.
+   */
+  void computeFieldOffsets(int tableTail) {
+    assert(fieldOffsets.isEmpty);
+    for (int fieldTail in fieldTails) {
+      int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail;
+      fieldOffsets.add(fieldOffset);
+    }
+  }
+
+  /**
+   * Outputs this VTable to [buf], which is is expected to be aligned to 16-bit
+   * and have at least [numOfUint16] 16-bit words available.
+   */
+  void output(ByteData buf, int bufOffset) {
+    // VTable size.
+    buf.setUint16(bufOffset, numOfUint16 * 2, Endianness.LITTLE_ENDIAN);
+    bufOffset += 2;
+    // Table size.
+    buf.setUint16(bufOffset, tableSize, Endianness.LITTLE_ENDIAN);
+    bufOffset += 2;
+    // Field offsets.
+    for (int fieldOffset in fieldOffsets) {
+      buf.setUint16(bufOffset, fieldOffset, Endianness.LITTLE_ENDIAN);
+      bufOffset += 2;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index c4fb417..97f9db6 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -7,8 +7,8 @@
 
 library analyzer.src.summary.format;
 
-import 'dart:convert';
 import 'base.dart' as base;
+import 'flat_buffers.dart' as fb;
 
 /**
  * Enum used to indicate the kind of entity referred to by a
@@ -41,115 +41,128 @@
   named,
 }
 
-/**
- * Information about a dependency that exists between one library and another
- * due to an "import" declaration.
- */
-class PrelinkedDependency extends base.SummaryClass {
-  String _uri;
-
-  PrelinkedDependency.fromJson(Map json)
-    : _uri = json["uri"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "uri": uri,
-  };
-
-  /**
-   * The relative URI used to import one library from the other.
-   */
-  String get uri => _uri ?? '';
-}
-
 class PrelinkedDependencyBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  PrelinkedDependencyBuilder(base.BuilderContext context);
+  String _uri;
+  List<String> _parts;
+
+  PrelinkedDependencyBuilder();
 
   /**
-   * The relative URI used to import one library from the other.
+   * The relative URI of the dependent library.  This URI is relative to the
+   * importing library, even if there are intervening `export` declarations.
+   * So, for example, if `a.dart` imports `b/c.dart` and `b/c.dart` exports
+   * `d/e.dart`, the URI listed for `a.dart`'s dependency on `e.dart` will be
+   * `b/d/e.dart`.
    */
   void set uri(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("uri"));
-    if (_value != null) {
-      _json["uri"] = _value;
-    }
+    _uri = _value;
   }
 
-  Map finish() {
+  /**
+   * URI for the compilation units listed in the library's `part` declarations.
+   * These URIs are relative to the importing library.
+   */
+  void set parts(List<String> _value) {
+    assert(!_finished);
+    _parts = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_uri;
+    fb.Offset offset_parts;
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder.writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(1, offset_parts);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-PrelinkedDependencyBuilder encodePrelinkedDependency(base.BuilderContext builderContext, {String uri}) {
-  PrelinkedDependencyBuilder builder = new PrelinkedDependencyBuilder(builderContext);
+PrelinkedDependencyBuilder encodePrelinkedDependency({String uri, List<String> parts}) {
+  PrelinkedDependencyBuilder builder = new PrelinkedDependencyBuilder();
   builder.uri = uri;
+  builder.parts = parts;
   return builder;
 }
 
 /**
- * Pre-linked summary of a library.
+ * Information about a dependency that exists between one library and another
+ * due to an "import" declaration.
  */
-class PrelinkedLibrary extends base.SummaryClass {
-  List<PrelinkedUnit> _units;
-  List<PrelinkedDependency> _dependencies;
-  List<int> _importDependencies;
+abstract class PrelinkedDependency extends base.SummaryClass {
 
-  PrelinkedLibrary.fromJson(Map json)
-    : _units = json["units"]?.map((x) => new PrelinkedUnit.fromJson(x))?.toList(),
-      _dependencies = json["dependencies"]?.map((x) => new PrelinkedDependency.fromJson(x))?.toList(),
-      _importDependencies = json["importDependencies"];
+  /**
+   * The relative URI of the dependent library.  This URI is relative to the
+   * importing library, even if there are intervening `export` declarations.
+   * So, for example, if `a.dart` imports `b/c.dart` and `b/c.dart` exports
+   * `d/e.dart`, the URI listed for `a.dart`'s dependency on `e.dart` will be
+   * `b/d/e.dart`.
+   */
+  String get uri;
+
+  /**
+   * URI for the compilation units listed in the library's `part` declarations.
+   * These URIs are relative to the importing library.
+   */
+  List<String> get parts;
+}
+
+class _PrelinkedDependencyReader extends fb.TableReader<_PrelinkedDependencyImpl> {
+  const _PrelinkedDependencyReader();
+
+  @override
+  _PrelinkedDependencyImpl createObject(fb.BufferPointer bp) => new _PrelinkedDependencyImpl(bp);
+}
+
+class _PrelinkedDependencyImpl implements PrelinkedDependency {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedDependencyImpl(this._bp);
+
+  String _uri;
+  List<String> _parts;
 
   @override
   Map<String, Object> toMap() => {
-    "units": units,
-    "dependencies": dependencies,
-    "importDependencies": importDependencies,
+    "uri": uri,
+    "parts": parts,
   };
 
-  PrelinkedLibrary.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _uri;
+  }
 
-  /**
-   * The pre-linked summary of all the compilation units constituting the
-   * library.  The summary of the defining compilation unit is listed first,
-   * followed by the summary of each part, in the order of the `part`
-   * declarations in the defining compilation unit.
-   */
-  List<PrelinkedUnit> get units => _units ?? const <PrelinkedUnit>[];
-
-  /**
-   * The libraries that this library depends on (either via an explicit import
-   * statement or via the implicit dependencies on `dart:core` and
-   * `dart:async`).  The first element of this array is a pseudo-dependency
-   * representing the library itself (it is also used for "dynamic").
-   *
-   * TODO(paulberry): consider removing this entirely and just using
-   * [UnlinkedLibrary.imports].
-   */
-  List<PrelinkedDependency> get dependencies => _dependencies ?? const <PrelinkedDependency>[];
-
-  /**
-   * For each import in [UnlinkedUnit.imports], an index into [dependencies]
-   * of the library being imported.
-   *
-   * TODO(paulberry): if [dependencies] is removed, this can be removed as
-   * well, since there will effectively be a one-to-one mapping.
-   */
-  List<int> get importDependencies => _importDependencies ?? const <int>[];
+  @override
+  List<String> get parts {
+    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    return _parts;
+  }
 }
 
 class PrelinkedLibraryBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  PrelinkedLibraryBuilder(base.BuilderContext context);
+  List<PrelinkedUnitBuilder> _units;
+  List<PrelinkedDependencyBuilder> _dependencies;
+  List<int> _importDependencies;
+
+  PrelinkedLibraryBuilder();
 
   /**
    * The pre-linked summary of all the compilation units constituting the
@@ -159,10 +172,7 @@
    */
   void set units(List<PrelinkedUnitBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("units"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["units"] = _value.map((b) => b.finish()).toList();
-    }
+    _units = _value;
   }
 
   /**
@@ -176,10 +186,7 @@
    */
   void set dependencies(List<PrelinkedDependencyBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("dependencies"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["dependencies"] = _value.map((b) => b.finish()).toList();
-    }
+    _dependencies = _value;
   }
 
   /**
@@ -191,23 +198,45 @@
    */
   void set importDependencies(List<int> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("importDependencies"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["importDependencies"] = _value.toList();
-    }
+    _importDependencies = _value;
   }
 
-  List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_units;
+    fb.Offset offset_dependencies;
+    fb.Offset offset_importDependencies;
+    if (!(_units == null || _units.isEmpty)) {
+      offset_units = fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_dependencies == null || _dependencies.isEmpty)) {
+      offset_dependencies = fbBuilder.writeList(_dependencies.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_importDependencies == null || _importDependencies.isEmpty)) {
+      offset_importDependencies = fbBuilder.writeListInt32(_importDependencies);
+    }
+    fbBuilder.startTable();
+    if (offset_units != null) {
+      fbBuilder.addOffset(0, offset_units);
+    }
+    if (offset_dependencies != null) {
+      fbBuilder.addOffset(1, offset_dependencies);
+    }
+    if (offset_importDependencies != null) {
+      fbBuilder.addOffset(2, offset_importDependencies);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-PrelinkedLibraryBuilder encodePrelinkedLibrary(base.BuilderContext builderContext, {List<PrelinkedUnitBuilder> units, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies}) {
-  PrelinkedLibraryBuilder builder = new PrelinkedLibraryBuilder(builderContext);
+PrelinkedLibraryBuilder encodePrelinkedLibrary({List<PrelinkedUnitBuilder> units, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies}) {
+  PrelinkedLibraryBuilder builder = new PrelinkedLibraryBuilder();
   builder.units = units;
   builder.dependencies = dependencies;
   builder.importDependencies = importDependencies;
@@ -215,61 +244,94 @@
 }
 
 /**
- * Information about the resolution of an [UnlinkedReference].
+ * Pre-linked summary of a library.
  */
-class PrelinkedReference extends base.SummaryClass {
+abstract class PrelinkedLibrary extends base.SummaryClass {
+  factory PrelinkedLibrary.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _PrelinkedLibraryReader().read(rootRef);
+  }
+
+  /**
+   * The pre-linked summary of all the compilation units constituting the
+   * library.  The summary of the defining compilation unit is listed first,
+   * followed by the summary of each part, in the order of the `part`
+   * declarations in the defining compilation unit.
+   */
+  List<PrelinkedUnit> get units;
+
+  /**
+   * The libraries that this library depends on (either via an explicit import
+   * statement or via the implicit dependencies on `dart:core` and
+   * `dart:async`).  The first element of this array is a pseudo-dependency
+   * representing the library itself (it is also used for "dynamic").
+   *
+   * TODO(paulberry): consider removing this entirely and just using
+   * [UnlinkedLibrary.imports].
+   */
+  List<PrelinkedDependency> get dependencies;
+
+  /**
+   * For each import in [UnlinkedUnit.imports], an index into [dependencies]
+   * of the library being imported.
+   *
+   * TODO(paulberry): if [dependencies] is removed, this can be removed as
+   * well, since there will effectively be a one-to-one mapping.
+   */
+  List<int> get importDependencies;
+}
+
+class _PrelinkedLibraryReader extends fb.TableReader<_PrelinkedLibraryImpl> {
+  const _PrelinkedLibraryReader();
+
+  @override
+  _PrelinkedLibraryImpl createObject(fb.BufferPointer bp) => new _PrelinkedLibraryImpl(bp);
+}
+
+class _PrelinkedLibraryImpl implements PrelinkedLibrary {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedLibraryImpl(this._bp);
+
+  List<PrelinkedUnit> _units;
+  List<PrelinkedDependency> _dependencies;
+  List<int> _importDependencies;
+
+  @override
+  Map<String, Object> toMap() => {
+    "units": units,
+    "dependencies": dependencies,
+    "importDependencies": importDependencies,
+  };
+
+  @override
+  List<PrelinkedUnit> get units {
+    _units ??= const fb.ListReader<PrelinkedUnit>(const _PrelinkedUnitReader()).vTableGet(_bp, 0, const <PrelinkedUnit>[]);
+    return _units;
+  }
+
+  @override
+  List<PrelinkedDependency> get dependencies {
+    _dependencies ??= const fb.ListReader<PrelinkedDependency>(const _PrelinkedDependencyReader()).vTableGet(_bp, 1, const <PrelinkedDependency>[]);
+    return _dependencies;
+  }
+
+  @override
+  List<int> get importDependencies {
+    _importDependencies ??= const fb.ListReader<int>(const fb.Int32Reader()).vTableGet(_bp, 2, const <int>[]);
+    return _importDependencies;
+  }
+}
+
+class PrelinkedReferenceBuilder {
+  bool _finished = false;
+
   int _dependency;
   PrelinkedReferenceKind _kind;
   int _unit;
   int _numTypeParameters;
 
-  PrelinkedReference.fromJson(Map json)
-    : _dependency = json["dependency"],
-      _kind = json["kind"] == null ? null : PrelinkedReferenceKind.values[json["kind"]],
-      _unit = json["unit"],
-      _numTypeParameters = json["numTypeParameters"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "dependency": dependency,
-    "kind": kind,
-    "unit": unit,
-    "numTypeParameters": numTypeParameters,
-  };
-
-  /**
-   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
-   * declares the entity being referred to.
-   */
-  int get dependency => _dependency ?? 0;
-
-  /**
-   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
-   * the kind is [PrelinkedReferenceKind.classOrEnum].
-   */
-  PrelinkedReferenceKind get kind => _kind ?? PrelinkedReferenceKind.classOrEnum;
-
-  /**
-   * Integer index indicating which unit in the imported library contains the
-   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
-   * zero represents the defining compilation unit, and nonzero values
-   * represent parts in the order of the corresponding `part` declarations.
-   */
-  int get unit => _unit ?? 0;
-
-  /**
-   * If the entity being referred to is generic, the number of type parameters
-   * it accepts.  Otherwise zero.
-   */
-  int get numTypeParameters => _numTypeParameters ?? 0;
-}
-
-class PrelinkedReferenceBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  PrelinkedReferenceBuilder(base.BuilderContext context);
+  PrelinkedReferenceBuilder();
 
   /**
    * Index into [PrelinkedLibrary.dependencies] indicating which imported library
@@ -277,10 +339,7 @@
    */
   void set dependency(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("dependency"));
-    if (_value != null) {
-      _json["dependency"] = _value;
-    }
+    _dependency = _value;
   }
 
   /**
@@ -289,10 +348,7 @@
    */
   void set kind(PrelinkedReferenceKind _value) {
     assert(!_finished);
-    assert(!_json.containsKey("kind"));
-    if (!(_value == null || _value == PrelinkedReferenceKind.classOrEnum)) {
-      _json["kind"] = _value.index;
-    }
+    _kind = _value;
   }
 
   /**
@@ -303,10 +359,7 @@
    */
   void set unit(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("unit"));
-    if (_value != null) {
-      _json["unit"] = _value;
-    }
+    _unit = _value;
   }
 
   /**
@@ -315,21 +368,31 @@
    */
   void set numTypeParameters(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("numTypeParameters"));
-    if (_value != null) {
-      _json["numTypeParameters"] = _value;
-    }
+    _numTypeParameters = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fbBuilder.startTable();
+    if (_dependency != null && _dependency != 0) {
+      fbBuilder.addInt32(0, _dependency);
+    }
+    if (_kind != null && _kind != PrelinkedReferenceKind.classOrEnum) {
+      fbBuilder.addInt32(1, _kind.index);
+    }
+    if (_unit != null && _unit != 0) {
+      fbBuilder.addInt32(2, _unit);
+    }
+    if (_numTypeParameters != null && _numTypeParameters != 0) {
+      fbBuilder.addInt32(3, _numTypeParameters);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-PrelinkedReferenceBuilder encodePrelinkedReference(base.BuilderContext builderContext, {int dependency, PrelinkedReferenceKind kind, int unit, int numTypeParameters}) {
-  PrelinkedReferenceBuilder builder = new PrelinkedReferenceBuilder(builderContext);
+PrelinkedReferenceBuilder encodePrelinkedReference({int dependency, PrelinkedReferenceKind kind, int unit, int numTypeParameters}) {
+  PrelinkedReferenceBuilder builder = new PrelinkedReferenceBuilder();
   builder.dependency = dependency;
   builder.kind = kind;
   builder.unit = unit;
@@ -338,32 +401,93 @@
 }
 
 /**
- * Pre-linked summary of a compilation unit.
+ * Information about the resolution of an [UnlinkedReference].
  */
-class PrelinkedUnit extends base.SummaryClass {
-  List<PrelinkedReference> _references;
+abstract class PrelinkedReference extends base.SummaryClass {
 
-  PrelinkedUnit.fromJson(Map json)
-    : _references = json["references"]?.map((x) => new PrelinkedReference.fromJson(x))?.toList();
+  /**
+   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * declares the entity being referred to.
+   */
+  int get dependency;
+
+  /**
+   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
+   * the kind is [PrelinkedReferenceKind.classOrEnum].
+   */
+  PrelinkedReferenceKind get kind;
+
+  /**
+   * Integer index indicating which unit in the imported library contains the
+   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  int get unit;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int get numTypeParameters;
+}
+
+class _PrelinkedReferenceReader extends fb.TableReader<_PrelinkedReferenceImpl> {
+  const _PrelinkedReferenceReader();
+
+  @override
+  _PrelinkedReferenceImpl createObject(fb.BufferPointer bp) => new _PrelinkedReferenceImpl(bp);
+}
+
+class _PrelinkedReferenceImpl implements PrelinkedReference {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedReferenceImpl(this._bp);
+
+  int _dependency;
+  PrelinkedReferenceKind _kind;
+  int _unit;
+  int _numTypeParameters;
 
   @override
   Map<String, Object> toMap() => {
-    "references": references,
+    "dependency": dependency,
+    "kind": kind,
+    "unit": unit,
+    "numTypeParameters": numTypeParameters,
   };
 
-  /**
-   * For each reference in [UnlinkedUnit.references], information about how
-   * that reference is resolved.
-   */
-  List<PrelinkedReference> get references => _references ?? const <PrelinkedReference>[];
+  @override
+  int get dependency {
+    _dependency ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _dependency;
+  }
+
+  @override
+  PrelinkedReferenceKind get kind {
+    _kind ??= PrelinkedReferenceKind.values[const fb.Int32Reader().vTableGet(_bp, 1, 0)];
+    return _kind;
+  }
+
+  @override
+  int get unit {
+    _unit ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _unit;
+  }
+
+  @override
+  int get numTypeParameters {
+    _numTypeParameters ??= const fb.Int32Reader().vTableGet(_bp, 3, 0);
+    return _numTypeParameters;
+  }
 }
 
 class PrelinkedUnitBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  PrelinkedUnitBuilder(base.BuilderContext context);
+  List<PrelinkedReferenceBuilder> _references;
+
+  PrelinkedUnitBuilder();
 
   /**
    * For each reference in [UnlinkedUnit.references], information about how
@@ -371,40 +495,207 @@
    */
   void set references(List<PrelinkedReferenceBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("references"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["references"] = _value.map((b) => b.finish()).toList();
-    }
+    _references = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_references;
+    if (!(_references == null || _references.isEmpty)) {
+      offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_references != null) {
+      fbBuilder.addOffset(0, offset_references);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-PrelinkedUnitBuilder encodePrelinkedUnit(base.BuilderContext builderContext, {List<PrelinkedReferenceBuilder> references}) {
-  PrelinkedUnitBuilder builder = new PrelinkedUnitBuilder(builderContext);
+PrelinkedUnitBuilder encodePrelinkedUnit({List<PrelinkedReferenceBuilder> references}) {
+  PrelinkedUnitBuilder builder = new PrelinkedUnitBuilder();
   builder.references = references;
   return builder;
 }
 
 /**
+ * Pre-linked summary of a compilation unit.
+ */
+abstract class PrelinkedUnit extends base.SummaryClass {
+
+  /**
+   * For each reference in [UnlinkedUnit.references], information about how
+   * that reference is resolved.
+   */
+  List<PrelinkedReference> get references;
+}
+
+class _PrelinkedUnitReader extends fb.TableReader<_PrelinkedUnitImpl> {
+  const _PrelinkedUnitReader();
+
+  @override
+  _PrelinkedUnitImpl createObject(fb.BufferPointer bp) => new _PrelinkedUnitImpl(bp);
+}
+
+class _PrelinkedUnitImpl implements PrelinkedUnit {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedUnitImpl(this._bp);
+
+  List<PrelinkedReference> _references;
+
+  @override
+  Map<String, Object> toMap() => {
+    "references": references,
+  };
+
+  @override
+  List<PrelinkedReference> get references {
+    _references ??= const fb.ListReader<PrelinkedReference>(const _PrelinkedReferenceReader()).vTableGet(_bp, 0, const <PrelinkedReference>[]);
+    return _references;
+  }
+}
+
+class SdkBundleBuilder {
+  bool _finished = false;
+
+  List<String> _prelinkedLibraryUris;
+  List<PrelinkedLibraryBuilder> _prelinkedLibraries;
+  List<String> _unlinkedUnitUris;
+  List<UnlinkedUnitBuilder> _unlinkedUnits;
+
+  SdkBundleBuilder();
+
+  /**
+   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   */
+  void set prelinkedLibraryUris(List<String> _value) {
+    assert(!_finished);
+    _prelinkedLibraryUris = _value;
+  }
+
+  /**
+   * Pre-linked libraries.
+   */
+  void set prelinkedLibraries(List<PrelinkedLibraryBuilder> _value) {
+    assert(!_finished);
+    _prelinkedLibraries = _value;
+  }
+
+  /**
+   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
+   */
+  void set unlinkedUnitUris(List<String> _value) {
+    assert(!_finished);
+    _unlinkedUnitUris = _value;
+  }
+
+  /**
+   * Unlinked information for the compilation units constituting the SDK.
+   */
+  void set unlinkedUnits(List<UnlinkedUnitBuilder> _value) {
+    assert(!_finished);
+    _unlinkedUnits = _value;
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_prelinkedLibraryUris;
+    fb.Offset offset_prelinkedLibraries;
+    fb.Offset offset_unlinkedUnitUris;
+    fb.Offset offset_unlinkedUnits;
+    if (!(_prelinkedLibraryUris == null || _prelinkedLibraryUris.isEmpty)) {
+      offset_prelinkedLibraryUris = fbBuilder.writeList(_prelinkedLibraryUris.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_prelinkedLibraries == null || _prelinkedLibraries.isEmpty)) {
+      offset_prelinkedLibraries = fbBuilder.writeList(_prelinkedLibraries.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_unlinkedUnitUris == null || _unlinkedUnitUris.isEmpty)) {
+      offset_unlinkedUnitUris = fbBuilder.writeList(_unlinkedUnitUris.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_unlinkedUnits == null || _unlinkedUnits.isEmpty)) {
+      offset_unlinkedUnits = fbBuilder.writeList(_unlinkedUnits.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_prelinkedLibraryUris != null) {
+      fbBuilder.addOffset(0, offset_prelinkedLibraryUris);
+    }
+    if (offset_prelinkedLibraries != null) {
+      fbBuilder.addOffset(1, offset_prelinkedLibraries);
+    }
+    if (offset_unlinkedUnitUris != null) {
+      fbBuilder.addOffset(2, offset_unlinkedUnitUris);
+    }
+    if (offset_unlinkedUnits != null) {
+      fbBuilder.addOffset(3, offset_unlinkedUnits);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+SdkBundleBuilder encodeSdkBundle({List<String> prelinkedLibraryUris, List<PrelinkedLibraryBuilder> prelinkedLibraries, List<String> unlinkedUnitUris, List<UnlinkedUnitBuilder> unlinkedUnits}) {
+  SdkBundleBuilder builder = new SdkBundleBuilder();
+  builder.prelinkedLibraryUris = prelinkedLibraryUris;
+  builder.prelinkedLibraries = prelinkedLibraries;
+  builder.unlinkedUnitUris = unlinkedUnitUris;
+  builder.unlinkedUnits = unlinkedUnits;
+  return builder;
+}
+
+/**
  * Information about SDK.
  */
-class SdkBundle extends base.SummaryClass {
+abstract class SdkBundle extends base.SummaryClass {
+  factory SdkBundle.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _SdkBundleReader().read(rootRef);
+  }
+
+  /**
+   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   */
+  List<String> get prelinkedLibraryUris;
+
+  /**
+   * Pre-linked libraries.
+   */
+  List<PrelinkedLibrary> get prelinkedLibraries;
+
+  /**
+   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
+   */
+  List<String> get unlinkedUnitUris;
+
+  /**
+   * Unlinked information for the compilation units constituting the SDK.
+   */
+  List<UnlinkedUnit> get unlinkedUnits;
+}
+
+class _SdkBundleReader extends fb.TableReader<_SdkBundleImpl> {
+  const _SdkBundleReader();
+
+  @override
+  _SdkBundleImpl createObject(fb.BufferPointer bp) => new _SdkBundleImpl(bp);
+}
+
+class _SdkBundleImpl implements SdkBundle {
+  final fb.BufferPointer _bp;
+
+  _SdkBundleImpl(this._bp);
+
   List<String> _prelinkedLibraryUris;
   List<PrelinkedLibrary> _prelinkedLibraries;
   List<String> _unlinkedUnitUris;
   List<UnlinkedUnit> _unlinkedUnits;
 
-  SdkBundle.fromJson(Map json)
-    : _prelinkedLibraryUris = json["prelinkedLibraryUris"],
-      _prelinkedLibraries = json["prelinkedLibraries"]?.map((x) => new PrelinkedLibrary.fromJson(x))?.toList(),
-      _unlinkedUnitUris = json["unlinkedUnitUris"],
-      _unlinkedUnits = json["unlinkedUnits"]?.map((x) => new UnlinkedUnit.fromJson(x))?.toList();
-
   @override
   Map<String, Object> toMap() => {
     "prelinkedLibraryUris": prelinkedLibraryUris,
@@ -413,209 +704,72 @@
     "unlinkedUnits": unlinkedUnits,
   };
 
-  SdkBundle.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
+  @override
+  List<String> get prelinkedLibraryUris {
+    _prelinkedLibraryUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
+    return _prelinkedLibraryUris;
+  }
 
-  /**
-   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
-   */
-  List<String> get prelinkedLibraryUris => _prelinkedLibraryUris ?? const <String>[];
+  @override
+  List<PrelinkedLibrary> get prelinkedLibraries {
+    _prelinkedLibraries ??= const fb.ListReader<PrelinkedLibrary>(const _PrelinkedLibraryReader()).vTableGet(_bp, 1, const <PrelinkedLibrary>[]);
+    return _prelinkedLibraries;
+  }
 
-  /**
-   * Pre-linked libraries.
-   */
-  List<PrelinkedLibrary> get prelinkedLibraries => _prelinkedLibraries ?? const <PrelinkedLibrary>[];
+  @override
+  List<String> get unlinkedUnitUris {
+    _unlinkedUnitUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 2, const <String>[]);
+    return _unlinkedUnitUris;
+  }
 
-  /**
-   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
-   */
-  List<String> get unlinkedUnitUris => _unlinkedUnitUris ?? const <String>[];
-
-  /**
-   * Unlinked information for the compilation units constituting the SDK.
-   */
-  List<UnlinkedUnit> get unlinkedUnits => _unlinkedUnits ?? const <UnlinkedUnit>[];
+  @override
+  List<UnlinkedUnit> get unlinkedUnits {
+    _unlinkedUnits ??= const fb.ListReader<UnlinkedUnit>(const _UnlinkedUnitReader()).vTableGet(_bp, 3, const <UnlinkedUnit>[]);
+    return _unlinkedUnits;
+  }
 }
 
-class SdkBundleBuilder {
-  final Map _json = {};
-
+class UnlinkedClassBuilder {
   bool _finished = false;
 
-  SdkBundleBuilder(base.BuilderContext context);
-
-  /**
-   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
-   */
-  void set prelinkedLibraryUris(List<String> _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("prelinkedLibraryUris"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["prelinkedLibraryUris"] = _value.toList();
-    }
-  }
-
-  /**
-   * Pre-linked libraries.
-   */
-  void set prelinkedLibraries(List<PrelinkedLibraryBuilder> _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("prelinkedLibraries"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["prelinkedLibraries"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  /**
-   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
-   */
-  void set unlinkedUnitUris(List<String> _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("unlinkedUnitUris"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["unlinkedUnitUris"] = _value.toList();
-    }
-  }
-
-  /**
-   * Unlinked information for the compilation units constituting the SDK.
-   */
-  void set unlinkedUnits(List<UnlinkedUnitBuilder> _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("unlinkedUnits"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["unlinkedUnits"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
-
-  Map finish() {
-    assert(!_finished);
-    _finished = true;
-    return _json;
-  }
-}
-
-SdkBundleBuilder encodeSdkBundle(base.BuilderContext builderContext, {List<String> prelinkedLibraryUris, List<PrelinkedLibraryBuilder> prelinkedLibraries, List<String> unlinkedUnitUris, List<UnlinkedUnitBuilder> unlinkedUnits}) {
-  SdkBundleBuilder builder = new SdkBundleBuilder(builderContext);
-  builder.prelinkedLibraryUris = prelinkedLibraryUris;
-  builder.prelinkedLibraries = prelinkedLibraries;
-  builder.unlinkedUnitUris = unlinkedUnitUris;
-  builder.unlinkedUnits = unlinkedUnits;
-  return builder;
-}
-
-/**
- * Unlinked summary information about a class declaration.
- */
-class UnlinkedClass extends base.SummaryClass {
   String _name;
-  List<UnlinkedTypeParam> _typeParameters;
-  UnlinkedTypeRef _supertype;
-  List<UnlinkedTypeRef> _mixins;
-  List<UnlinkedTypeRef> _interfaces;
-  List<UnlinkedVariable> _fields;
-  List<UnlinkedExecutable> _executables;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+  UnlinkedTypeRefBuilder _supertype;
+  List<UnlinkedTypeRefBuilder> _mixins;
+  List<UnlinkedTypeRefBuilder> _interfaces;
+  List<UnlinkedVariableBuilder> _fields;
+  List<UnlinkedExecutableBuilder> _executables;
   bool _isAbstract;
   bool _isMixinApplication;
   bool _hasNoSupertype;
 
-  UnlinkedClass.fromJson(Map json)
-    : _name = json["name"],
-      _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
-      _supertype = json["supertype"] == null ? null : new UnlinkedTypeRef.fromJson(json["supertype"]),
-      _mixins = json["mixins"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList(),
-      _interfaces = json["interfaces"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList(),
-      _fields = json["fields"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList(),
-      _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
-      _isAbstract = json["isAbstract"],
-      _isMixinApplication = json["isMixinApplication"],
-      _hasNoSupertype = json["hasNoSupertype"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "typeParameters": typeParameters,
-    "supertype": supertype,
-    "mixins": mixins,
-    "interfaces": interfaces,
-    "fields": fields,
-    "executables": executables,
-    "isAbstract": isAbstract,
-    "isMixinApplication": isMixinApplication,
-    "hasNoSupertype": hasNoSupertype,
-  };
-
-  /**
-   * Name of the class.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * Type parameters of the class, if any.
-   */
-  List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
-
-  /**
-   * Supertype of the class, or `null` if either (a) the class doesn't
-   * explicitly declare a supertype (and hence has supertype `Object`), or (b)
-   * the class *is* `Object` (and hence has no supertype).
-   */
-  UnlinkedTypeRef get supertype => _supertype;
-
-  /**
-   * Mixins appearing in a `with` clause, if any.
-   */
-  List<UnlinkedTypeRef> get mixins => _mixins ?? const <UnlinkedTypeRef>[];
-
-  /**
-   * Interfaces appearing in an `implements` clause, if any.
-   */
-  List<UnlinkedTypeRef> get interfaces => _interfaces ?? const <UnlinkedTypeRef>[];
-
-  /**
-   * Field declarations contained in the class.
-   */
-  List<UnlinkedVariable> get fields => _fields ?? const <UnlinkedVariable>[];
-
-  /**
-   * Executable objects (methods, getters, and setters) contained in the class.
-   */
-  List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
-
-  /**
-   * Indicates whether the class is declared with the `abstract` keyword.
-   */
-  bool get isAbstract => _isAbstract ?? false;
-
-  /**
-   * Indicates whether the class is declared using mixin application syntax.
-   */
-  bool get isMixinApplication => _isMixinApplication ?? false;
-
-  /**
-   * Indicates whether this class is the core "Object" class (and hence has no
-   * supertype)
-   */
-  bool get hasNoSupertype => _hasNoSupertype ?? false;
-}
-
-class UnlinkedClassBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  UnlinkedClassBuilder(base.BuilderContext context);
+  UnlinkedClassBuilder();
 
   /**
    * Name of the class.
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the class name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the class, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
   }
 
   /**
@@ -623,10 +777,7 @@
    */
   void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("typeParameters"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["typeParameters"] = _value.map((b) => b.finish()).toList();
-    }
+    _typeParameters = _value;
   }
 
   /**
@@ -636,10 +787,7 @@
    */
   void set supertype(UnlinkedTypeRefBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("supertype"));
-    if (_value != null) {
-      _json["supertype"] = _value.finish();
-    }
+    _supertype = _value;
   }
 
   /**
@@ -647,10 +795,7 @@
    */
   void set mixins(List<UnlinkedTypeRefBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("mixins"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["mixins"] = _value.map((b) => b.finish()).toList();
-    }
+    _mixins = _value;
   }
 
   /**
@@ -658,10 +803,7 @@
    */
   void set interfaces(List<UnlinkedTypeRefBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("interfaces"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["interfaces"] = _value.map((b) => b.finish()).toList();
-    }
+    _interfaces = _value;
   }
 
   /**
@@ -669,10 +811,7 @@
    */
   void set fields(List<UnlinkedVariableBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("fields"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["fields"] = _value.map((b) => b.finish()).toList();
-    }
+    _fields = _value;
   }
 
   /**
@@ -680,10 +819,7 @@
    */
   void set executables(List<UnlinkedExecutableBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("executables"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["executables"] = _value.map((b) => b.finish()).toList();
-    }
+    _executables = _value;
   }
 
   /**
@@ -691,10 +827,7 @@
    */
   void set isAbstract(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isAbstract"));
-    if (_value != null) {
-      _json["isAbstract"] = _value;
-    }
+    _isAbstract = _value;
   }
 
   /**
@@ -702,10 +835,7 @@
    */
   void set isMixinApplication(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isMixinApplication"));
-    if (_value != null) {
-      _json["isMixinApplication"] = _value;
-    }
+    _isMixinApplication = _value;
   }
 
   /**
@@ -714,22 +844,90 @@
    */
   void set hasNoSupertype(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("hasNoSupertype"));
-    if (_value != null) {
-      _json["hasNoSupertype"] = _value;
-    }
+    _hasNoSupertype = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_typeParameters;
+    fb.Offset offset_supertype;
+    fb.Offset offset_mixins;
+    fb.Offset offset_interfaces;
+    fb.Offset offset_fields;
+    fb.Offset offset_executables;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder.writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_supertype != null) {
+      offset_supertype = _supertype.finish(fbBuilder);
+    }
+    if (!(_mixins == null || _mixins.isEmpty)) {
+      offset_mixins = fbBuilder.writeList(_mixins.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_interfaces == null || _interfaces.isEmpty)) {
+      offset_interfaces = fbBuilder.writeList(_interfaces.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_fields == null || _fields.isEmpty)) {
+      offset_fields = fbBuilder.writeList(_fields.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_executables == null || _executables.isEmpty)) {
+      offset_executables = fbBuilder.writeList(_executables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(3, offset_typeParameters);
+    }
+    if (offset_supertype != null) {
+      fbBuilder.addOffset(4, offset_supertype);
+    }
+    if (offset_mixins != null) {
+      fbBuilder.addOffset(5, offset_mixins);
+    }
+    if (offset_interfaces != null) {
+      fbBuilder.addOffset(6, offset_interfaces);
+    }
+    if (offset_fields != null) {
+      fbBuilder.addOffset(7, offset_fields);
+    }
+    if (offset_executables != null) {
+      fbBuilder.addOffset(8, offset_executables);
+    }
+    if (_isAbstract == true) {
+      fbBuilder.addBool(9, true);
+    }
+    if (_isMixinApplication == true) {
+      fbBuilder.addBool(10, true);
+    }
+    if (_hasNoSupertype == true) {
+      fbBuilder.addBool(11, true);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedClassBuilder encodeUnlinkedClass(base.BuilderContext builderContext, {String name, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder supertype, List<UnlinkedTypeRefBuilder> mixins, List<UnlinkedTypeRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication, bool hasNoSupertype}) {
-  UnlinkedClassBuilder builder = new UnlinkedClassBuilder(builderContext);
+UnlinkedClassBuilder encodeUnlinkedClass({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder supertype, List<UnlinkedTypeRefBuilder> mixins, List<UnlinkedTypeRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication, bool hasNoSupertype}) {
+  UnlinkedClassBuilder builder = new UnlinkedClassBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
   builder.typeParameters = typeParameters;
   builder.supertype = supertype;
   builder.mixins = mixins;
@@ -743,50 +941,203 @@
 }
 
 /**
- * Unlinked summary information about a `show` or `hide` combinator in an
- * import or export declaration.
+ * Unlinked summary information about a class declaration.
  */
-class UnlinkedCombinator extends base.SummaryClass {
-  List<String> _shows;
-  List<String> _hides;
+abstract class UnlinkedClass extends base.SummaryClass {
 
-  UnlinkedCombinator.fromJson(Map json)
-    : _shows = json["shows"],
-      _hides = json["hides"];
+  /**
+   * Name of the class.
+   */
+  String get name;
+
+  /**
+   * Offset of the class name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the class, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Type parameters of the class, if any.
+   */
+  List<UnlinkedTypeParam> get typeParameters;
+
+  /**
+   * Supertype of the class, or `null` if either (a) the class doesn't
+   * explicitly declare a supertype (and hence has supertype `Object`), or (b)
+   * the class *is* `Object` (and hence has no supertype).
+   */
+  UnlinkedTypeRef get supertype;
+
+  /**
+   * Mixins appearing in a `with` clause, if any.
+   */
+  List<UnlinkedTypeRef> get mixins;
+
+  /**
+   * Interfaces appearing in an `implements` clause, if any.
+   */
+  List<UnlinkedTypeRef> get interfaces;
+
+  /**
+   * Field declarations contained in the class.
+   */
+  List<UnlinkedVariable> get fields;
+
+  /**
+   * Executable objects (methods, getters, and setters) contained in the class.
+   */
+  List<UnlinkedExecutable> get executables;
+
+  /**
+   * Indicates whether the class is declared with the `abstract` keyword.
+   */
+  bool get isAbstract;
+
+  /**
+   * Indicates whether the class is declared using mixin application syntax.
+   */
+  bool get isMixinApplication;
+
+  /**
+   * Indicates whether this class is the core "Object" class (and hence has no
+   * supertype)
+   */
+  bool get hasNoSupertype;
+}
+
+class _UnlinkedClassReader extends fb.TableReader<_UnlinkedClassImpl> {
+  const _UnlinkedClassReader();
+
+  @override
+  _UnlinkedClassImpl createObject(fb.BufferPointer bp) => new _UnlinkedClassImpl(bp);
+}
+
+class _UnlinkedClassImpl implements UnlinkedClass {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedClassImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _supertype;
+  List<UnlinkedTypeRef> _mixins;
+  List<UnlinkedTypeRef> _interfaces;
+  List<UnlinkedVariable> _fields;
+  List<UnlinkedExecutable> _executables;
+  bool _isAbstract;
+  bool _isMixinApplication;
+  bool _hasNoSupertype;
 
   @override
   Map<String, Object> toMap() => {
-    "shows": shows,
-    "hides": hides,
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "supertype": supertype,
+    "mixins": mixins,
+    "interfaces": interfaces,
+    "fields": fields,
+    "executables": executables,
+    "isAbstract": isAbstract,
+    "isMixinApplication": isMixinApplication,
+    "hasNoSupertype": hasNoSupertype,
   };
 
-  /**
-   * List of names which are shown.  Empty if this is a `hide` combinator.
-   */
-  List<String> get shows => _shows ?? const <String>[];
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
 
-  /**
-   * List of names which are hidden.  Empty if this is a `show` combinator.
-   */
-  List<String> get hides => _hides ?? const <String>[];
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 3, const <UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+
+  @override
+  UnlinkedTypeRef get supertype {
+    _supertype ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+    return _supertype;
+  }
+
+  @override
+  List<UnlinkedTypeRef> get mixins {
+    _mixins ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 5, const <UnlinkedTypeRef>[]);
+    return _mixins;
+  }
+
+  @override
+  List<UnlinkedTypeRef> get interfaces {
+    _interfaces ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 6, const <UnlinkedTypeRef>[]);
+    return _interfaces;
+  }
+
+  @override
+  List<UnlinkedVariable> get fields {
+    _fields ??= const fb.ListReader<UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 7, const <UnlinkedVariable>[]);
+    return _fields;
+  }
+
+  @override
+  List<UnlinkedExecutable> get executables {
+    _executables ??= const fb.ListReader<UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 8, const <UnlinkedExecutable>[]);
+    return _executables;
+  }
+
+  @override
+  bool get isAbstract {
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bp, 9, false);
+    return _isAbstract;
+  }
+
+  @override
+  bool get isMixinApplication {
+    _isMixinApplication ??= const fb.BoolReader().vTableGet(_bp, 10, false);
+    return _isMixinApplication;
+  }
+
+  @override
+  bool get hasNoSupertype {
+    _hasNoSupertype ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    return _hasNoSupertype;
+  }
 }
 
 class UnlinkedCombinatorBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedCombinatorBuilder(base.BuilderContext context);
+  List<String> _shows;
+  List<String> _hides;
+
+  UnlinkedCombinatorBuilder();
 
   /**
    * List of names which are shown.  Empty if this is a `hide` combinator.
    */
   void set shows(List<String> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("shows"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["shows"] = _value.toList();
-    }
+    _shows = _value;
   }
 
   /**
@@ -794,70 +1145,255 @@
    */
   void set hides(List<String> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("hides"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["hides"] = _value.toList();
-    }
+    _hides = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_shows;
+    fb.Offset offset_hides;
+    if (!(_shows == null || _shows.isEmpty)) {
+      offset_shows = fbBuilder.writeList(_shows.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_hides == null || _hides.isEmpty)) {
+      offset_hides = fbBuilder.writeList(_hides.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_shows != null) {
+      fbBuilder.addOffset(0, offset_shows);
+    }
+    if (offset_hides != null) {
+      fbBuilder.addOffset(1, offset_hides);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedCombinatorBuilder encodeUnlinkedCombinator(base.BuilderContext builderContext, {List<String> shows, List<String> hides}) {
-  UnlinkedCombinatorBuilder builder = new UnlinkedCombinatorBuilder(builderContext);
+UnlinkedCombinatorBuilder encodeUnlinkedCombinator({List<String> shows, List<String> hides}) {
+  UnlinkedCombinatorBuilder builder = new UnlinkedCombinatorBuilder();
   builder.shows = shows;
   builder.hides = hides;
   return builder;
 }
 
 /**
- * Unlinked summary information about an enum declaration.
+ * Unlinked summary information about a `show` or `hide` combinator in an
+ * import or export declaration.
  */
-class UnlinkedEnum extends base.SummaryClass {
-  String _name;
-  List<UnlinkedEnumValue> _values;
+abstract class UnlinkedCombinator extends base.SummaryClass {
 
-  UnlinkedEnum.fromJson(Map json)
-    : _name = json["name"],
-      _values = json["values"]?.map((x) => new UnlinkedEnumValue.fromJson(x))?.toList();
+  /**
+   * List of names which are shown.  Empty if this is a `hide` combinator.
+   */
+  List<String> get shows;
+
+  /**
+   * List of names which are hidden.  Empty if this is a `show` combinator.
+   */
+  List<String> get hides;
+}
+
+class _UnlinkedCombinatorReader extends fb.TableReader<_UnlinkedCombinatorImpl> {
+  const _UnlinkedCombinatorReader();
+
+  @override
+  _UnlinkedCombinatorImpl createObject(fb.BufferPointer bp) => new _UnlinkedCombinatorImpl(bp);
+}
+
+class _UnlinkedCombinatorImpl implements UnlinkedCombinator {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedCombinatorImpl(this._bp);
+
+  List<String> _shows;
+  List<String> _hides;
 
   @override
   Map<String, Object> toMap() => {
-    "name": name,
-    "values": values,
+    "shows": shows,
+    "hides": hides,
   };
 
-  /**
-   * Name of the enum type.
-   */
-  String get name => _name ?? '';
+  @override
+  List<String> get shows {
+    _shows ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
+    return _shows;
+  }
+
+  @override
+  List<String> get hides {
+    _hides ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    return _hides;
+  }
+}
+
+class UnlinkedDocumentationCommentBuilder {
+  bool _finished = false;
+
+  String _text;
+  int _offset;
+  int _length;
+
+  UnlinkedDocumentationCommentBuilder();
 
   /**
-   * Values listed in the enum declaration, in declaration order.
+   * Text of the documentation comment, with '\r\n' replaced by '\n'.
+   *
+   * References appearing within the doc comment in square brackets are not
+   * specially encoded.
    */
-  List<UnlinkedEnumValue> get values => _values ?? const <UnlinkedEnumValue>[];
+  void set text(String _value) {
+    assert(!_finished);
+    _text = _value;
+  }
+
+  /**
+   * Offset of the beginning of the documentation comment relative to the
+   * beginning of the file.
+   */
+  void set offset(int _value) {
+    assert(!_finished);
+    _offset = _value;
+  }
+
+  /**
+   * Length of the documentation comment (prior to replacing '\r\n' with '\n').
+   */
+  void set length(int _value) {
+    assert(!_finished);
+    _length = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_text;
+    if (_text != null) {
+      offset_text = fbBuilder.writeString(_text);
+    }
+    fbBuilder.startTable();
+    if (offset_text != null) {
+      fbBuilder.addOffset(0, offset_text);
+    }
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addInt32(1, _offset);
+    }
+    if (_length != null && _length != 0) {
+      fbBuilder.addInt32(2, _length);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedDocumentationCommentBuilder encodeUnlinkedDocumentationComment({String text, int offset, int length}) {
+  UnlinkedDocumentationCommentBuilder builder = new UnlinkedDocumentationCommentBuilder();
+  builder.text = text;
+  builder.offset = offset;
+  builder.length = length;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a documentation comment.
+ */
+abstract class UnlinkedDocumentationComment extends base.SummaryClass {
+
+  /**
+   * Text of the documentation comment, with '\r\n' replaced by '\n'.
+   *
+   * References appearing within the doc comment in square brackets are not
+   * specially encoded.
+   */
+  String get text;
+
+  /**
+   * Offset of the beginning of the documentation comment relative to the
+   * beginning of the file.
+   */
+  int get offset;
+
+  /**
+   * Length of the documentation comment (prior to replacing '\r\n' with '\n').
+   */
+  int get length;
+}
+
+class _UnlinkedDocumentationCommentReader extends fb.TableReader<_UnlinkedDocumentationCommentImpl> {
+  const _UnlinkedDocumentationCommentReader();
+
+  @override
+  _UnlinkedDocumentationCommentImpl createObject(fb.BufferPointer bp) => new _UnlinkedDocumentationCommentImpl(bp);
+}
+
+class _UnlinkedDocumentationCommentImpl implements UnlinkedDocumentationComment {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedDocumentationCommentImpl(this._bp);
+
+  String _text;
+  int _offset;
+  int _length;
+
+  @override
+  Map<String, Object> toMap() => {
+    "text": text,
+    "offset": offset,
+    "length": length,
+  };
+
+  @override
+  String get text {
+    _text ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _text;
+  }
+
+  @override
+  int get offset {
+    _offset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _offset;
+  }
+
+  @override
+  int get length {
+    _length ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _length;
+  }
 }
 
 class UnlinkedEnumBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedEnumBuilder(base.BuilderContext context);
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedEnumValueBuilder> _values;
+
+  UnlinkedEnumBuilder();
 
   /**
    * Name of the enum type.
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the enum name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the enum, or `null` if there is no documentation
+   * comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
   }
 
   /**
@@ -865,87 +1401,268 @@
    */
   void set values(List<UnlinkedEnumValueBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("values"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["values"] = _value.map((b) => b.finish()).toList();
-    }
+    _values = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_values;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_values == null || _values.isEmpty)) {
+      offset_values = fbBuilder.writeList(_values.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_values != null) {
+      fbBuilder.addOffset(3, offset_values);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedEnumBuilder encodeUnlinkedEnum(base.BuilderContext builderContext, {String name, List<UnlinkedEnumValueBuilder> values}) {
-  UnlinkedEnumBuilder builder = new UnlinkedEnumBuilder(builderContext);
+UnlinkedEnumBuilder encodeUnlinkedEnum({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedEnumValueBuilder> values}) {
+  UnlinkedEnumBuilder builder = new UnlinkedEnumBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
   builder.values = values;
   return builder;
 }
 
 /**
+ * Unlinked summary information about an enum declaration.
+ */
+abstract class UnlinkedEnum extends base.SummaryClass {
+
+  /**
+   * Name of the enum type.
+   */
+  String get name;
+
+  /**
+   * Offset of the enum name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the enum, or `null` if there is no documentation
+   * comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Values listed in the enum declaration, in declaration order.
+   */
+  List<UnlinkedEnumValue> get values;
+}
+
+class _UnlinkedEnumReader extends fb.TableReader<_UnlinkedEnumImpl> {
+  const _UnlinkedEnumReader();
+
+  @override
+  _UnlinkedEnumImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumImpl(bp);
+}
+
+class _UnlinkedEnumImpl implements UnlinkedEnum {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedEnumImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedEnumValue> _values;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "values": values,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedEnumValue> get values {
+    _values ??= const fb.ListReader<UnlinkedEnumValue>(const _UnlinkedEnumValueReader()).vTableGet(_bp, 3, const <UnlinkedEnumValue>[]);
+    return _values;
+  }
+}
+
+class UnlinkedEnumValueBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+
+  UnlinkedEnumValueBuilder();
+
+  /**
+   * Name of the enumerated value.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the enum value name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the enum value, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedEnumValueBuilder encodeUnlinkedEnumValue({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment}) {
+  UnlinkedEnumValueBuilder builder = new UnlinkedEnumValueBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  return builder;
+}
+
+/**
  * Unlinked summary information about a single enumerated value in an enum
  * declaration.
  */
-class UnlinkedEnumValue extends base.SummaryClass {
-  String _name;
+abstract class UnlinkedEnumValue extends base.SummaryClass {
 
-  UnlinkedEnumValue.fromJson(Map json)
-    : _name = json["name"];
+  /**
+   * Name of the enumerated value.
+   */
+  String get name;
+
+  /**
+   * Offset of the enum value name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the enum value, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+}
+
+class _UnlinkedEnumValueReader extends fb.TableReader<_UnlinkedEnumValueImpl> {
+  const _UnlinkedEnumValueReader();
+
+  @override
+  _UnlinkedEnumValueImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumValueImpl(bp);
+}
+
+class _UnlinkedEnumValueImpl implements UnlinkedEnumValue {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedEnumValueImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
 
   @override
   Map<String, Object> toMap() => {
     "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
   };
 
-  /**
-   * Name of the enumerated value.
-   */
-  String get name => _name ?? '';
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
 }
 
-class UnlinkedEnumValueBuilder {
-  final Map _json = {};
-
+class UnlinkedExecutableBuilder {
   bool _finished = false;
 
-  UnlinkedEnumValueBuilder(base.BuilderContext context);
-
-  /**
-   * Name of the enumerated value.
-   */
-  void set name(String _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
-  }
-
-  Map finish() {
-    assert(!_finished);
-    _finished = true;
-    return _json;
-  }
-}
-
-UnlinkedEnumValueBuilder encodeUnlinkedEnumValue(base.BuilderContext builderContext, {String name}) {
-  UnlinkedEnumValueBuilder builder = new UnlinkedEnumValueBuilder(builderContext);
-  builder.name = name;
-  return builder;
-}
-
-/**
- * Unlinked summary information about a function, method, getter, or setter
- * declaration.
- */
-class UnlinkedExecutable extends base.SummaryClass {
   String _name;
-  List<UnlinkedTypeParam> _typeParameters;
-  UnlinkedTypeRef _returnType;
-  List<UnlinkedParam> _parameters;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+  UnlinkedTypeRefBuilder _returnType;
+  List<UnlinkedParamBuilder> _parameters;
   UnlinkedExecutableKind _kind;
   bool _isAbstract;
   bool _isStatic;
@@ -954,109 +1671,7 @@
   bool _hasImplicitReturnType;
   bool _isExternal;
 
-  UnlinkedExecutable.fromJson(Map json)
-    : _name = json["name"],
-      _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
-      _returnType = json["returnType"] == null ? null : new UnlinkedTypeRef.fromJson(json["returnType"]),
-      _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList(),
-      _kind = json["kind"] == null ? null : UnlinkedExecutableKind.values[json["kind"]],
-      _isAbstract = json["isAbstract"],
-      _isStatic = json["isStatic"],
-      _isConst = json["isConst"],
-      _isFactory = json["isFactory"],
-      _hasImplicitReturnType = json["hasImplicitReturnType"],
-      _isExternal = json["isExternal"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "typeParameters": typeParameters,
-    "returnType": returnType,
-    "parameters": parameters,
-    "kind": kind,
-    "isAbstract": isAbstract,
-    "isStatic": isStatic,
-    "isConst": isConst,
-    "isFactory": isFactory,
-    "hasImplicitReturnType": hasImplicitReturnType,
-    "isExternal": isExternal,
-  };
-
-  /**
-   * Name of the executable.  For setters, this includes the trailing "=".  For
-   * named constructors, this excludes the class name and excludes the ".".
-   * For unnamed constructors, this is the empty string.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * Type parameters of the executable, if any.  Empty if support for generic
-   * method syntax is disabled.
-   */
-  List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
-
-  /**
-   * Declared return type of the executable.  Absent if the return type is
-   * `void`.  Note that when strong mode is enabled, the actual return type may
-   * be different due to type inference.
-   */
-  UnlinkedTypeRef get returnType => _returnType;
-
-  /**
-   * Parameters of the executable, if any.  Note that getters have no
-   * parameters (hence this will be the empty list), and setters have a single
-   * parameter.
-   */
-  List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
-
-  /**
-   * The kind of the executable (function/method, getter, setter, or
-   * constructor).
-   */
-  UnlinkedExecutableKind get kind => _kind ?? UnlinkedExecutableKind.functionOrMethod;
-
-  /**
-   * Indicates whether the executable is declared using the `abstract` keyword.
-   */
-  bool get isAbstract => _isAbstract ?? false;
-
-  /**
-   * Indicates whether the executable is declared using the `static` keyword.
-   *
-   * Note that for top level executables, this flag is false, since they are
-   * not declared using the `static` keyword (even though they are considered
-   * static for semantic purposes).
-   */
-  bool get isStatic => _isStatic ?? false;
-
-  /**
-   * Indicates whether the executable is declared using the `const` keyword.
-   */
-  bool get isConst => _isConst ?? false;
-
-  /**
-   * Indicates whether the executable is declared using the `factory` keyword.
-   */
-  bool get isFactory => _isFactory ?? false;
-
-  /**
-   * Indicates whether the executable lacks an explicit return type
-   * declaration.  False for constructors and setters.
-   */
-  bool get hasImplicitReturnType => _hasImplicitReturnType ?? false;
-
-  /**
-   * Indicates whether the executable is declared using the `external` keyword.
-   */
-  bool get isExternal => _isExternal ?? false;
-}
-
-class UnlinkedExecutableBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  UnlinkedExecutableBuilder(base.BuilderContext context);
+  UnlinkedExecutableBuilder();
 
   /**
    * Name of the executable.  For setters, this includes the trailing "=".  For
@@ -1065,10 +1680,27 @@
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the executable name relative to the beginning of the file.  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the offset of the class name (i.e. the
+   * offset of the second "C" in "class C { C(); }").
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the executable, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
   }
 
   /**
@@ -1077,23 +1709,17 @@
    */
   void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("typeParameters"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["typeParameters"] = _value.map((b) => b.finish()).toList();
-    }
+    _typeParameters = _value;
   }
 
   /**
    * Declared return type of the executable.  Absent if the return type is
-   * `void`.  Note that when strong mode is enabled, the actual return type may
-   * be different due to type inference.
+   * `void` or the executable is a constructor.  Note that when strong mode is
+   * enabled, the actual return type may be different due to type inference.
    */
   void set returnType(UnlinkedTypeRefBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("returnType"));
-    if (_value != null) {
-      _json["returnType"] = _value.finish();
-    }
+    _returnType = _value;
   }
 
   /**
@@ -1103,10 +1729,7 @@
    */
   void set parameters(List<UnlinkedParamBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("parameters"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["parameters"] = _value.map((b) => b.finish()).toList();
-    }
+    _parameters = _value;
   }
 
   /**
@@ -1115,10 +1738,7 @@
    */
   void set kind(UnlinkedExecutableKind _value) {
     assert(!_finished);
-    assert(!_json.containsKey("kind"));
-    if (!(_value == null || _value == UnlinkedExecutableKind.functionOrMethod)) {
-      _json["kind"] = _value.index;
-    }
+    _kind = _value;
   }
 
   /**
@@ -1126,10 +1746,7 @@
    */
   void set isAbstract(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isAbstract"));
-    if (_value != null) {
-      _json["isAbstract"] = _value;
-    }
+    _isAbstract = _value;
   }
 
   /**
@@ -1141,10 +1758,7 @@
    */
   void set isStatic(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isStatic"));
-    if (_value != null) {
-      _json["isStatic"] = _value;
-    }
+    _isStatic = _value;
   }
 
   /**
@@ -1152,10 +1766,7 @@
    */
   void set isConst(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isConst"));
-    if (_value != null) {
-      _json["isConst"] = _value;
-    }
+    _isConst = _value;
   }
 
   /**
@@ -1163,10 +1774,7 @@
    */
   void set isFactory(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isFactory"));
-    if (_value != null) {
-      _json["isFactory"] = _value;
-    }
+    _isFactory = _value;
   }
 
   /**
@@ -1175,10 +1783,7 @@
    */
   void set hasImplicitReturnType(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("hasImplicitReturnType"));
-    if (_value != null) {
-      _json["hasImplicitReturnType"] = _value;
-    }
+    _hasImplicitReturnType = _value;
   }
 
   /**
@@ -1186,22 +1791,81 @@
    */
   void set isExternal(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isExternal"));
-    if (_value != null) {
-      _json["isExternal"] = _value;
-    }
+    _isExternal = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_typeParameters;
+    fb.Offset offset_returnType;
+    fb.Offset offset_parameters;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder.writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_returnType != null) {
+      offset_returnType = _returnType.finish(fbBuilder);
+    }
+    if (!(_parameters == null || _parameters.isEmpty)) {
+      offset_parameters = fbBuilder.writeList(_parameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(3, offset_typeParameters);
+    }
+    if (offset_returnType != null) {
+      fbBuilder.addOffset(4, offset_returnType);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(5, offset_parameters);
+    }
+    if (_kind != null && _kind != UnlinkedExecutableKind.functionOrMethod) {
+      fbBuilder.addInt32(6, _kind.index);
+    }
+    if (_isAbstract == true) {
+      fbBuilder.addBool(7, true);
+    }
+    if (_isStatic == true) {
+      fbBuilder.addBool(8, true);
+    }
+    if (_isConst == true) {
+      fbBuilder.addBool(9, true);
+    }
+    if (_isFactory == true) {
+      fbBuilder.addBool(10, true);
+    }
+    if (_hasImplicitReturnType == true) {
+      fbBuilder.addBool(11, true);
+    }
+    if (_isExternal == true) {
+      fbBuilder.addBool(12, true);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedExecutableBuilder encodeUnlinkedExecutable(base.BuilderContext builderContext, {String name, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory, bool hasImplicitReturnType, bool isExternal}) {
-  UnlinkedExecutableBuilder builder = new UnlinkedExecutableBuilder(builderContext);
+UnlinkedExecutableBuilder encodeUnlinkedExecutable({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory, bool hasImplicitReturnType, bool isExternal}) {
+  UnlinkedExecutableBuilder builder = new UnlinkedExecutableBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
   builder.typeParameters = typeParameters;
   builder.returnType = returnType;
   builder.parameters = parameters;
@@ -1216,49 +1880,356 @@
 }
 
 /**
- * Unlinked summary information about an export declaration.
+ * Unlinked summary information about a function, method, getter, or setter
+ * declaration.
  */
-class UnlinkedExport extends base.SummaryClass {
-  String _uri;
-  List<UnlinkedCombinator> _combinators;
+abstract class UnlinkedExecutable extends base.SummaryClass {
 
-  UnlinkedExport.fromJson(Map json)
-    : _uri = json["uri"],
-      _combinators = json["combinators"]?.map((x) => new UnlinkedCombinator.fromJson(x))?.toList();
+  /**
+   * Name of the executable.  For setters, this includes the trailing "=".  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the empty string.
+   */
+  String get name;
+
+  /**
+   * Offset of the executable name relative to the beginning of the file.  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the offset of the class name (i.e. the
+   * offset of the second "C" in "class C { C(); }").
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the executable, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Type parameters of the executable, if any.  Empty if support for generic
+   * method syntax is disabled.
+   */
+  List<UnlinkedTypeParam> get typeParameters;
+
+  /**
+   * Declared return type of the executable.  Absent if the return type is
+   * `void` or the executable is a constructor.  Note that when strong mode is
+   * enabled, the actual return type may be different due to type inference.
+   */
+  UnlinkedTypeRef get returnType;
+
+  /**
+   * Parameters of the executable, if any.  Note that getters have no
+   * parameters (hence this will be the empty list), and setters have a single
+   * parameter.
+   */
+  List<UnlinkedParam> get parameters;
+
+  /**
+   * The kind of the executable (function/method, getter, setter, or
+   * constructor).
+   */
+  UnlinkedExecutableKind get kind;
+
+  /**
+   * Indicates whether the executable is declared using the `abstract` keyword.
+   */
+  bool get isAbstract;
+
+  /**
+   * Indicates whether the executable is declared using the `static` keyword.
+   *
+   * Note that for top level executables, this flag is false, since they are
+   * not declared using the `static` keyword (even though they are considered
+   * static for semantic purposes).
+   */
+  bool get isStatic;
+
+  /**
+   * Indicates whether the executable is declared using the `const` keyword.
+   */
+  bool get isConst;
+
+  /**
+   * Indicates whether the executable is declared using the `factory` keyword.
+   */
+  bool get isFactory;
+
+  /**
+   * Indicates whether the executable lacks an explicit return type
+   * declaration.  False for constructors and setters.
+   */
+  bool get hasImplicitReturnType;
+
+  /**
+   * Indicates whether the executable is declared using the `external` keyword.
+   */
+  bool get isExternal;
+}
+
+class _UnlinkedExecutableReader extends fb.TableReader<_UnlinkedExecutableImpl> {
+  const _UnlinkedExecutableReader();
+
+  @override
+  _UnlinkedExecutableImpl createObject(fb.BufferPointer bp) => new _UnlinkedExecutableImpl(bp);
+}
+
+class _UnlinkedExecutableImpl implements UnlinkedExecutable {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedExecutableImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _returnType;
+  List<UnlinkedParam> _parameters;
+  UnlinkedExecutableKind _kind;
+  bool _isAbstract;
+  bool _isStatic;
+  bool _isConst;
+  bool _isFactory;
+  bool _hasImplicitReturnType;
+  bool _isExternal;
 
   @override
   Map<String, Object> toMap() => {
-    "uri": uri,
-    "combinators": combinators,
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "returnType": returnType,
+    "parameters": parameters,
+    "kind": kind,
+    "isAbstract": isAbstract,
+    "isStatic": isStatic,
+    "isConst": isConst,
+    "isFactory": isFactory,
+    "hasImplicitReturnType": hasImplicitReturnType,
+    "isExternal": isExternal,
   };
 
-  /**
-   * URI used in the source code to reference the exported library.
-   */
-  String get uri => _uri ?? '';
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
 
-  /**
-   * Combinators contained in this import declaration.
-   */
-  List<UnlinkedCombinator> get combinators => _combinators ?? const <UnlinkedCombinator>[];
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 3, const <UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+
+  @override
+  UnlinkedTypeRef get returnType {
+    _returnType ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+    return _returnType;
+  }
+
+  @override
+  List<UnlinkedParam> get parameters {
+    _parameters ??= const fb.ListReader<UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 5, const <UnlinkedParam>[]);
+    return _parameters;
+  }
+
+  @override
+  UnlinkedExecutableKind get kind {
+    _kind ??= UnlinkedExecutableKind.values[const fb.Int32Reader().vTableGet(_bp, 6, 0)];
+    return _kind;
+  }
+
+  @override
+  bool get isAbstract {
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    return _isAbstract;
+  }
+
+  @override
+  bool get isStatic {
+    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 8, false);
+    return _isStatic;
+  }
+
+  @override
+  bool get isConst {
+    _isConst ??= const fb.BoolReader().vTableGet(_bp, 9, false);
+    return _isConst;
+  }
+
+  @override
+  bool get isFactory {
+    _isFactory ??= const fb.BoolReader().vTableGet(_bp, 10, false);
+    return _isFactory;
+  }
+
+  @override
+  bool get hasImplicitReturnType {
+    _hasImplicitReturnType ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    return _hasImplicitReturnType;
+  }
+
+  @override
+  bool get isExternal {
+    _isExternal ??= const fb.BoolReader().vTableGet(_bp, 12, false);
+    return _isExternal;
+  }
 }
 
-class UnlinkedExportBuilder {
-  final Map _json = {};
-
+class UnlinkedExportNonPublicBuilder {
   bool _finished = false;
 
-  UnlinkedExportBuilder(base.BuilderContext context);
+  int _offset;
+  int _uriOffset;
+  int _uriEnd;
+
+  UnlinkedExportNonPublicBuilder();
+
+  /**
+   * Offset of the "export" keyword.
+   */
+  void set offset(int _value) {
+    assert(!_finished);
+    _offset = _value;
+  }
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  void set uriOffset(int _value) {
+    assert(!_finished);
+    _uriOffset = _value;
+  }
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  void set uriEnd(int _value) {
+    assert(!_finished);
+    _uriEnd = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fbBuilder.startTable();
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addInt32(0, _offset);
+    }
+    if (_uriOffset != null && _uriOffset != 0) {
+      fbBuilder.addInt32(1, _uriOffset);
+    }
+    if (_uriEnd != null && _uriEnd != 0) {
+      fbBuilder.addInt32(2, _uriEnd);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedExportNonPublicBuilder encodeUnlinkedExportNonPublic({int offset, int uriOffset, int uriEnd}) {
+  UnlinkedExportNonPublicBuilder builder = new UnlinkedExportNonPublicBuilder();
+  builder.offset = offset;
+  builder.uriOffset = uriOffset;
+  builder.uriEnd = uriEnd;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about an export declaration (stored outside
+ * [UnlinkedPublicNamespace]).
+ */
+abstract class UnlinkedExportNonPublic extends base.SummaryClass {
+
+  /**
+   * Offset of the "export" keyword.
+   */
+  int get offset;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  int get uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  int get uriEnd;
+}
+
+class _UnlinkedExportNonPublicReader extends fb.TableReader<_UnlinkedExportNonPublicImpl> {
+  const _UnlinkedExportNonPublicReader();
+
+  @override
+  _UnlinkedExportNonPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportNonPublicImpl(bp);
+}
+
+class _UnlinkedExportNonPublicImpl implements UnlinkedExportNonPublic {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedExportNonPublicImpl(this._bp);
+
+  int _offset;
+  int _uriOffset;
+  int _uriEnd;
+
+  @override
+  Map<String, Object> toMap() => {
+    "offset": offset,
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+  };
+
+  @override
+  int get offset {
+    _offset ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _offset;
+  }
+
+  @override
+  int get uriOffset {
+    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _uriOffset;
+  }
+
+  @override
+  int get uriEnd {
+    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _uriEnd;
+  }
+}
+
+class UnlinkedExportPublicBuilder {
+  bool _finished = false;
+
+  String _uri;
+  List<UnlinkedCombinatorBuilder> _combinators;
+
+  UnlinkedExportPublicBuilder();
 
   /**
    * URI used in the source code to reference the exported library.
    */
   void set uri(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("uri"));
-    if (_value != null) {
-      _json["uri"] = _value;
-    }
+    _uri = _value;
   }
 
   /**
@@ -1266,106 +2237,110 @@
    */
   void set combinators(List<UnlinkedCombinatorBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("combinators"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["combinators"] = _value.map((b) => b.finish()).toList();
-    }
+    _combinators = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_uri;
+    fb.Offset offset_combinators;
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    if (!(_combinators == null || _combinators.isEmpty)) {
+      offset_combinators = fbBuilder.writeList(_combinators.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    if (offset_combinators != null) {
+      fbBuilder.addOffset(1, offset_combinators);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedExportBuilder encodeUnlinkedExport(base.BuilderContext builderContext, {String uri, List<UnlinkedCombinatorBuilder> combinators}) {
-  UnlinkedExportBuilder builder = new UnlinkedExportBuilder(builderContext);
+UnlinkedExportPublicBuilder encodeUnlinkedExportPublic({String uri, List<UnlinkedCombinatorBuilder> combinators}) {
+  UnlinkedExportPublicBuilder builder = new UnlinkedExportPublicBuilder();
   builder.uri = uri;
   builder.combinators = combinators;
   return builder;
 }
 
 /**
- * Unlinked summary information about an import declaration.
+ * Unlinked summary information about an export declaration (stored inside
+ * [UnlinkedPublicNamespace]).
  */
-class UnlinkedImport extends base.SummaryClass {
-  String _uri;
-  int _offset;
-  int _prefixReference;
-  List<UnlinkedCombinator> _combinators;
-  bool _isDeferred;
-  bool _isImplicit;
-
-  UnlinkedImport.fromJson(Map json)
-    : _uri = json["uri"],
-      _offset = json["offset"],
-      _prefixReference = json["prefixReference"],
-      _combinators = json["combinators"]?.map((x) => new UnlinkedCombinator.fromJson(x))?.toList(),
-      _isDeferred = json["isDeferred"],
-      _isImplicit = json["isImplicit"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "uri": uri,
-    "offset": offset,
-    "prefixReference": prefixReference,
-    "combinators": combinators,
-    "isDeferred": isDeferred,
-    "isImplicit": isImplicit,
-  };
+abstract class UnlinkedExportPublic extends base.SummaryClass {
 
   /**
-   * URI used in the source code to reference the imported library.
+   * URI used in the source code to reference the exported library.
    */
-  String get uri => _uri ?? '';
-
-  /**
-   * If [isImplicit] is false, offset of the "import" keyword.  If [isImplicit]
-   * is true, zero.
-   */
-  int get offset => _offset ?? 0;
-
-  /**
-   * Index into [UnlinkedUnit.references] of the prefix declared by this
-   * import declaration, or zero if this import declaration declares no prefix.
-   *
-   * Note that multiple imports can declare the same prefix.
-   */
-  int get prefixReference => _prefixReference ?? 0;
+  String get uri;
 
   /**
    * Combinators contained in this import declaration.
    */
-  List<UnlinkedCombinator> get combinators => _combinators ?? const <UnlinkedCombinator>[];
+  List<UnlinkedCombinator> get combinators;
+}
 
-  /**
-   * Indicates whether the import declaration uses the `deferred` keyword.
-   */
-  bool get isDeferred => _isDeferred ?? false;
+class _UnlinkedExportPublicReader extends fb.TableReader<_UnlinkedExportPublicImpl> {
+  const _UnlinkedExportPublicReader();
 
-  /**
-   * Indicates whether the import declaration is implicit.
-   */
-  bool get isImplicit => _isImplicit ?? false;
+  @override
+  _UnlinkedExportPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportPublicImpl(bp);
+}
+
+class _UnlinkedExportPublicImpl implements UnlinkedExportPublic {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedExportPublicImpl(this._bp);
+
+  String _uri;
+  List<UnlinkedCombinator> _combinators;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "combinators": combinators,
+  };
+
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _uri;
+  }
+
+  @override
+  List<UnlinkedCombinator> get combinators {
+    _combinators ??= const fb.ListReader<UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bp, 1, const <UnlinkedCombinator>[]);
+    return _combinators;
+  }
 }
 
 class UnlinkedImportBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedImportBuilder(base.BuilderContext context);
+  String _uri;
+  int _offset;
+  int _prefixReference;
+  List<UnlinkedCombinatorBuilder> _combinators;
+  bool _isDeferred;
+  bool _isImplicit;
+  int _uriOffset;
+  int _uriEnd;
+  int _prefixOffset;
+
+  UnlinkedImportBuilder();
 
   /**
    * URI used in the source code to reference the imported library.
    */
   void set uri(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("uri"));
-    if (_value != null) {
-      _json["uri"] = _value;
-    }
+    _uri = _value;
   }
 
   /**
@@ -1374,10 +2349,7 @@
    */
   void set offset(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("offset"));
-    if (_value != null) {
-      _json["offset"] = _value;
-    }
+    _offset = _value;
   }
 
   /**
@@ -1388,10 +2360,7 @@
    */
   void set prefixReference(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("prefixReference"));
-    if (_value != null) {
-      _json["prefixReference"] = _value;
-    }
+    _prefixReference = _value;
   }
 
   /**
@@ -1399,10 +2368,7 @@
    */
   void set combinators(List<UnlinkedCombinatorBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("combinators"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["combinators"] = _value.map((b) => b.finish()).toList();
-    }
+    _combinators = _value;
   }
 
   /**
@@ -1410,10 +2376,7 @@
    */
   void set isDeferred(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isDeferred"));
-    if (_value != null) {
-      _json["isDeferred"] = _value;
-    }
+    _isDeferred = _value;
   }
 
   /**
@@ -1421,120 +2384,269 @@
    */
   void set isImplicit(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isImplicit"));
-    if (_value != null) {
-      _json["isImplicit"] = _value;
-    }
+    _isImplicit = _value;
   }
 
-  Map finish() {
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.  If [isImplicit] is true, zero.
+   */
+  void set uriOffset(int _value) {
+    assert(!_finished);
+    _uriOffset = _value;
+  }
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.  If [isImplicit] is true, zero.
+   */
+  void set uriEnd(int _value) {
+    assert(!_finished);
+    _uriEnd = _value;
+  }
+
+  /**
+   * Offset of the prefix name relative to the beginning of the file, or zero
+   * if there is no prefix.
+   */
+  void set prefixOffset(int _value) {
+    assert(!_finished);
+    _prefixOffset = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_uri;
+    fb.Offset offset_combinators;
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    if (!(_combinators == null || _combinators.isEmpty)) {
+      offset_combinators = fbBuilder.writeList(_combinators.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addInt32(1, _offset);
+    }
+    if (_prefixReference != null && _prefixReference != 0) {
+      fbBuilder.addInt32(2, _prefixReference);
+    }
+    if (offset_combinators != null) {
+      fbBuilder.addOffset(3, offset_combinators);
+    }
+    if (_isDeferred == true) {
+      fbBuilder.addBool(4, true);
+    }
+    if (_isImplicit == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_uriOffset != null && _uriOffset != 0) {
+      fbBuilder.addInt32(6, _uriOffset);
+    }
+    if (_uriEnd != null && _uriEnd != 0) {
+      fbBuilder.addInt32(7, _uriEnd);
+    }
+    if (_prefixOffset != null && _prefixOffset != 0) {
+      fbBuilder.addInt32(8, _prefixOffset);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedImportBuilder encodeUnlinkedImport(base.BuilderContext builderContext, {String uri, int offset, int prefixReference, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit}) {
-  UnlinkedImportBuilder builder = new UnlinkedImportBuilder(builderContext);
+UnlinkedImportBuilder encodeUnlinkedImport({String uri, int offset, int prefixReference, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit, int uriOffset, int uriEnd, int prefixOffset}) {
+  UnlinkedImportBuilder builder = new UnlinkedImportBuilder();
   builder.uri = uri;
   builder.offset = offset;
   builder.prefixReference = prefixReference;
   builder.combinators = combinators;
   builder.isDeferred = isDeferred;
   builder.isImplicit = isImplicit;
+  builder.uriOffset = uriOffset;
+  builder.uriEnd = uriEnd;
+  builder.prefixOffset = prefixOffset;
   return builder;
 }
 
 /**
- * Unlinked summary information about a function parameter.
+ * Unlinked summary information about an import declaration.
  */
-class UnlinkedParam extends base.SummaryClass {
+abstract class UnlinkedImport extends base.SummaryClass {
+
+  /**
+   * URI used in the source code to reference the imported library.
+   */
+  String get uri;
+
+  /**
+   * If [isImplicit] is false, offset of the "import" keyword.  If [isImplicit]
+   * is true, zero.
+   */
+  int get offset;
+
+  /**
+   * Index into [UnlinkedUnit.references] of the prefix declared by this
+   * import declaration, or zero if this import declaration declares no prefix.
+   *
+   * Note that multiple imports can declare the same prefix.
+   */
+  int get prefixReference;
+
+  /**
+   * Combinators contained in this import declaration.
+   */
+  List<UnlinkedCombinator> get combinators;
+
+  /**
+   * Indicates whether the import declaration uses the `deferred` keyword.
+   */
+  bool get isDeferred;
+
+  /**
+   * Indicates whether the import declaration is implicit.
+   */
+  bool get isImplicit;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.  If [isImplicit] is true, zero.
+   */
+  int get uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.  If [isImplicit] is true, zero.
+   */
+  int get uriEnd;
+
+  /**
+   * Offset of the prefix name relative to the beginning of the file, or zero
+   * if there is no prefix.
+   */
+  int get prefixOffset;
+}
+
+class _UnlinkedImportReader extends fb.TableReader<_UnlinkedImportImpl> {
+  const _UnlinkedImportReader();
+
+  @override
+  _UnlinkedImportImpl createObject(fb.BufferPointer bp) => new _UnlinkedImportImpl(bp);
+}
+
+class _UnlinkedImportImpl implements UnlinkedImport {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedImportImpl(this._bp);
+
+  String _uri;
+  int _offset;
+  int _prefixReference;
+  List<UnlinkedCombinator> _combinators;
+  bool _isDeferred;
+  bool _isImplicit;
+  int _uriOffset;
+  int _uriEnd;
+  int _prefixOffset;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "offset": offset,
+    "prefixReference": prefixReference,
+    "combinators": combinators,
+    "isDeferred": isDeferred,
+    "isImplicit": isImplicit,
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+    "prefixOffset": prefixOffset,
+  };
+
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _uri;
+  }
+
+  @override
+  int get offset {
+    _offset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _offset;
+  }
+
+  @override
+  int get prefixReference {
+    _prefixReference ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _prefixReference;
+  }
+
+  @override
+  List<UnlinkedCombinator> get combinators {
+    _combinators ??= const fb.ListReader<UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bp, 3, const <UnlinkedCombinator>[]);
+    return _combinators;
+  }
+
+  @override
+  bool get isDeferred {
+    _isDeferred ??= const fb.BoolReader().vTableGet(_bp, 4, false);
+    return _isDeferred;
+  }
+
+  @override
+  bool get isImplicit {
+    _isImplicit ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isImplicit;
+  }
+
+  @override
+  int get uriOffset {
+    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 6, 0);
+    return _uriOffset;
+  }
+
+  @override
+  int get uriEnd {
+    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 7, 0);
+    return _uriEnd;
+  }
+
+  @override
+  int get prefixOffset {
+    _prefixOffset ??= const fb.Int32Reader().vTableGet(_bp, 8, 0);
+    return _prefixOffset;
+  }
+}
+
+class UnlinkedParamBuilder {
+  bool _finished = false;
+
   String _name;
-  UnlinkedTypeRef _type;
-  List<UnlinkedParam> _parameters;
+  int _nameOffset;
+  UnlinkedTypeRefBuilder _type;
+  List<UnlinkedParamBuilder> _parameters;
   UnlinkedParamKind _kind;
   bool _isFunctionTyped;
   bool _isInitializingFormal;
   bool _hasImplicitType;
 
-  UnlinkedParam.fromJson(Map json)
-    : _name = json["name"],
-      _type = json["type"] == null ? null : new UnlinkedTypeRef.fromJson(json["type"]),
-      _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList(),
-      _kind = json["kind"] == null ? null : UnlinkedParamKind.values[json["kind"]],
-      _isFunctionTyped = json["isFunctionTyped"],
-      _isInitializingFormal = json["isInitializingFormal"],
-      _hasImplicitType = json["hasImplicitType"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "type": type,
-    "parameters": parameters,
-    "kind": kind,
-    "isFunctionTyped": isFunctionTyped,
-    "isInitializingFormal": isInitializingFormal,
-    "hasImplicitType": hasImplicitType,
-  };
-
-  /**
-   * Name of the parameter.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * If [isFunctionTyped] is `true`, the declared return type.  If
-   * [isFunctionTyped] is `false`, the declared type.  Absent if
-   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
-   * that when strong mode is enabled, the actual type may be different due to
-   * type inference.
-   */
-  UnlinkedTypeRef get type => _type;
-
-  /**
-   * If [isFunctionTyped] is `true`, the parameters of the function type.
-   */
-  List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
-
-  /**
-   * Kind of the parameter.
-   */
-  UnlinkedParamKind get kind => _kind ?? UnlinkedParamKind.required;
-
-  /**
-   * Indicates whether this is a function-typed parameter.
-   */
-  bool get isFunctionTyped => _isFunctionTyped ?? false;
-
-  /**
-   * Indicates whether this is an initializing formal parameter (i.e. it is
-   * declared using `this.` syntax).
-   */
-  bool get isInitializingFormal => _isInitializingFormal ?? false;
-
-  /**
-   * Indicates whether this parameter lacks an explicit type declaration.
-   * Always false for a function-typed parameter.
-   */
-  bool get hasImplicitType => _hasImplicitType ?? false;
-}
-
-class UnlinkedParamBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  UnlinkedParamBuilder(base.BuilderContext context);
+  UnlinkedParamBuilder();
 
   /**
    * Name of the parameter.
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the parameter name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
   }
 
   /**
@@ -1546,10 +2658,7 @@
    */
   void set type(UnlinkedTypeRefBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("type"));
-    if (_value != null) {
-      _json["type"] = _value.finish();
-    }
+    _type = _value;
   }
 
   /**
@@ -1557,10 +2666,7 @@
    */
   void set parameters(List<UnlinkedParamBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("parameters"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["parameters"] = _value.map((b) => b.finish()).toList();
-    }
+    _parameters = _value;
   }
 
   /**
@@ -1568,10 +2674,7 @@
    */
   void set kind(UnlinkedParamKind _value) {
     assert(!_finished);
-    assert(!_json.containsKey("kind"));
-    if (!(_value == null || _value == UnlinkedParamKind.required)) {
-      _json["kind"] = _value.index;
-    }
+    _kind = _value;
   }
 
   /**
@@ -1579,10 +2682,7 @@
    */
   void set isFunctionTyped(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isFunctionTyped"));
-    if (_value != null) {
-      _json["isFunctionTyped"] = _value;
-    }
+    _isFunctionTyped = _value;
   }
 
   /**
@@ -1591,10 +2691,7 @@
    */
   void set isInitializingFormal(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isInitializingFormal"));
-    if (_value != null) {
-      _json["isInitializingFormal"] = _value;
-    }
+    _isInitializingFormal = _value;
   }
 
   /**
@@ -1603,22 +2700,57 @@
    */
   void set hasImplicitType(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("hasImplicitType"));
-    if (_value != null) {
-      _json["hasImplicitType"] = _value;
-    }
+    _hasImplicitType = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_type;
+    fb.Offset offset_parameters;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_type != null) {
+      offset_type = _type.finish(fbBuilder);
+    }
+    if (!(_parameters == null || _parameters.isEmpty)) {
+      offset_parameters = fbBuilder.writeList(_parameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_type != null) {
+      fbBuilder.addOffset(2, offset_type);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(3, offset_parameters);
+    }
+    if (_kind != null && _kind != UnlinkedParamKind.required) {
+      fbBuilder.addInt32(4, _kind.index);
+    }
+    if (_isFunctionTyped == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_isInitializingFormal == true) {
+      fbBuilder.addBool(6, true);
+    }
+    if (_hasImplicitType == true) {
+      fbBuilder.addBool(7, true);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedParamBuilder encodeUnlinkedParam(base.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal, bool hasImplicitType}) {
-  UnlinkedParamBuilder builder = new UnlinkedParamBuilder(builderContext);
+UnlinkedParamBuilder encodeUnlinkedParam({String name, int nameOffset, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal, bool hasImplicitType}) {
+  UnlinkedParamBuilder builder = new UnlinkedParamBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
   builder.type = type;
   builder.parameters = parameters;
   builder.kind = kind;
@@ -1629,53 +2761,298 @@
 }
 
 /**
- * Unlinked summary information about a part declaration.
+ * Unlinked summary information about a function parameter.
  */
-class UnlinkedPart extends base.SummaryClass {
-  String _uri;
+abstract class UnlinkedParam extends base.SummaryClass {
 
-  UnlinkedPart.fromJson(Map json)
-    : _uri = json["uri"];
+  /**
+   * Name of the parameter.
+   */
+  String get name;
+
+  /**
+   * Offset of the parameter name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * If [isFunctionTyped] is `true`, the declared return type.  If
+   * [isFunctionTyped] is `false`, the declared type.  Absent if
+   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
+   * that when strong mode is enabled, the actual type may be different due to
+   * type inference.
+   */
+  UnlinkedTypeRef get type;
+
+  /**
+   * If [isFunctionTyped] is `true`, the parameters of the function type.
+   */
+  List<UnlinkedParam> get parameters;
+
+  /**
+   * Kind of the parameter.
+   */
+  UnlinkedParamKind get kind;
+
+  /**
+   * Indicates whether this is a function-typed parameter.
+   */
+  bool get isFunctionTyped;
+
+  /**
+   * Indicates whether this is an initializing formal parameter (i.e. it is
+   * declared using `this.` syntax).
+   */
+  bool get isInitializingFormal;
+
+  /**
+   * Indicates whether this parameter lacks an explicit type declaration.
+   * Always false for a function-typed parameter.
+   */
+  bool get hasImplicitType;
+}
+
+class _UnlinkedParamReader extends fb.TableReader<_UnlinkedParamImpl> {
+  const _UnlinkedParamReader();
+
+  @override
+  _UnlinkedParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedParamImpl(bp);
+}
+
+class _UnlinkedParamImpl implements UnlinkedParam {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedParamImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRef _type;
+  List<UnlinkedParam> _parameters;
+  UnlinkedParamKind _kind;
+  bool _isFunctionTyped;
+  bool _isInitializingFormal;
+  bool _hasImplicitType;
 
   @override
   Map<String, Object> toMap() => {
-    "uri": uri,
+    "name": name,
+    "nameOffset": nameOffset,
+    "type": type,
+    "parameters": parameters,
+    "kind": kind,
+    "isFunctionTyped": isFunctionTyped,
+    "isInitializingFormal": isInitializingFormal,
+    "hasImplicitType": hasImplicitType,
   };
 
-  /**
-   * String used in the compilation unit to refer to the part file.
-   */
-  String get uri => _uri ?? '';
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedTypeRef get type {
+    _type ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 2, null);
+    return _type;
+  }
+
+  @override
+  List<UnlinkedParam> get parameters {
+    _parameters ??= const fb.ListReader<UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 3, const <UnlinkedParam>[]);
+    return _parameters;
+  }
+
+  @override
+  UnlinkedParamKind get kind {
+    _kind ??= UnlinkedParamKind.values[const fb.Int32Reader().vTableGet(_bp, 4, 0)];
+    return _kind;
+  }
+
+  @override
+  bool get isFunctionTyped {
+    _isFunctionTyped ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isFunctionTyped;
+  }
+
+  @override
+  bool get isInitializingFormal {
+    _isInitializingFormal ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    return _isInitializingFormal;
+  }
+
+  @override
+  bool get hasImplicitType {
+    _hasImplicitType ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    return _hasImplicitType;
+  }
 }
 
 class UnlinkedPartBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedPartBuilder(base.BuilderContext context);
+  int _uriOffset;
+  int _uriEnd;
+
+  UnlinkedPartBuilder();
 
   /**
-   * String used in the compilation unit to refer to the part file.
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
    */
-  void set uri(String _value) {
+  void set uriOffset(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("uri"));
-    if (_value != null) {
-      _json["uri"] = _value;
-    }
+    _uriOffset = _value;
   }
 
-  Map finish() {
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  void set uriEnd(int _value) {
+    assert(!_finished);
+    _uriEnd = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fbBuilder.startTable();
+    if (_uriOffset != null && _uriOffset != 0) {
+      fbBuilder.addInt32(0, _uriOffset);
+    }
+    if (_uriEnd != null && _uriEnd != 0) {
+      fbBuilder.addInt32(1, _uriEnd);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedPartBuilder encodeUnlinkedPart(base.BuilderContext builderContext, {String uri}) {
-  UnlinkedPartBuilder builder = new UnlinkedPartBuilder(builderContext);
-  builder.uri = uri;
+UnlinkedPartBuilder encodeUnlinkedPart({int uriOffset, int uriEnd}) {
+  UnlinkedPartBuilder builder = new UnlinkedPartBuilder();
+  builder.uriOffset = uriOffset;
+  builder.uriEnd = uriEnd;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a part declaration.
+ */
+abstract class UnlinkedPart extends base.SummaryClass {
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  int get uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  int get uriEnd;
+}
+
+class _UnlinkedPartReader extends fb.TableReader<_UnlinkedPartImpl> {
+  const _UnlinkedPartReader();
+
+  @override
+  _UnlinkedPartImpl createObject(fb.BufferPointer bp) => new _UnlinkedPartImpl(bp);
+}
+
+class _UnlinkedPartImpl implements UnlinkedPart {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedPartImpl(this._bp);
+
+  int _uriOffset;
+  int _uriEnd;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+  };
+
+  @override
+  int get uriOffset {
+    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _uriOffset;
+  }
+
+  @override
+  int get uriEnd {
+    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _uriEnd;
+  }
+}
+
+class UnlinkedPublicNameBuilder {
+  bool _finished = false;
+
+  String _name;
+  PrelinkedReferenceKind _kind;
+  int _numTypeParameters;
+
+  UnlinkedPublicNameBuilder();
+
+  /**
+   * The name itself.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * The kind of object referred to by the name.
+   */
+  void set kind(PrelinkedReferenceKind _value) {
+    assert(!_finished);
+    _kind = _value;
+  }
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  void set numTypeParameters(int _value) {
+    assert(!_finished);
+    _numTypeParameters = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_kind != null && _kind != PrelinkedReferenceKind.classOrEnum) {
+      fbBuilder.addInt32(1, _kind.index);
+    }
+    if (_numTypeParameters != null && _numTypeParameters != 0) {
+      fbBuilder.addInt32(2, _numTypeParameters);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedPublicNameBuilder encodeUnlinkedPublicName({String name, PrelinkedReferenceKind kind, int numTypeParameters}) {
+  UnlinkedPublicNameBuilder builder = new UnlinkedPublicNameBuilder();
+  builder.name = name;
+  builder.kind = kind;
+  builder.numTypeParameters = numTypeParameters;
   return builder;
 }
 
@@ -1693,123 +3070,75 @@
  * elsewhere in the summary.  Consider reducing the redundancy to reduce
  * summary size.
  */
-class UnlinkedPublicName extends base.SummaryClass {
+abstract class UnlinkedPublicName extends base.SummaryClass {
+
+  /**
+   * The name itself.
+   */
+  String get name;
+
+  /**
+   * The kind of object referred to by the name.
+   */
+  PrelinkedReferenceKind get kind;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int get numTypeParameters;
+}
+
+class _UnlinkedPublicNameReader extends fb.TableReader<_UnlinkedPublicNameImpl> {
+  const _UnlinkedPublicNameReader();
+
+  @override
+  _UnlinkedPublicNameImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNameImpl(bp);
+}
+
+class _UnlinkedPublicNameImpl implements UnlinkedPublicName {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedPublicNameImpl(this._bp);
+
   String _name;
   PrelinkedReferenceKind _kind;
-
-  UnlinkedPublicName.fromJson(Map json)
-    : _name = json["name"],
-      _kind = json["kind"] == null ? null : PrelinkedReferenceKind.values[json["kind"]];
+  int _numTypeParameters;
 
   @override
   Map<String, Object> toMap() => {
     "name": name,
     "kind": kind,
+    "numTypeParameters": numTypeParameters,
   };
 
-  /**
-   * The name itself.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * The kind of object referred to by the name.
-   */
-  PrelinkedReferenceKind get kind => _kind ?? PrelinkedReferenceKind.classOrEnum;
-}
-
-class UnlinkedPublicNameBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  UnlinkedPublicNameBuilder(base.BuilderContext context);
-
-  /**
-   * The name itself.
-   */
-  void set name(String _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
-  }
-
-  /**
-   * The kind of object referred to by the name.
-   */
-  void set kind(PrelinkedReferenceKind _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("kind"));
-    if (!(_value == null || _value == PrelinkedReferenceKind.classOrEnum)) {
-      _json["kind"] = _value.index;
-    }
-  }
-
-  Map finish() {
-    assert(!_finished);
-    _finished = true;
-    return _json;
-  }
-}
-
-UnlinkedPublicNameBuilder encodeUnlinkedPublicName(base.BuilderContext builderContext, {String name, PrelinkedReferenceKind kind}) {
-  UnlinkedPublicNameBuilder builder = new UnlinkedPublicNameBuilder(builderContext);
-  builder.name = name;
-  builder.kind = kind;
-  return builder;
-}
-
-/**
- * Unlinked summary information about what a compilation unit contributes to a
- * library's public namespace.  This is the subset of [UnlinkedUnit] that is
- * required from dependent libraries in order to perform prelinking.
- */
-class UnlinkedPublicNamespace extends base.SummaryClass {
-  List<UnlinkedPublicName> _names;
-  List<UnlinkedExport> _exports;
-  List<UnlinkedPart> _parts;
-
-  UnlinkedPublicNamespace.fromJson(Map json)
-    : _names = json["names"]?.map((x) => new UnlinkedPublicName.fromJson(x))?.toList(),
-      _exports = json["exports"]?.map((x) => new UnlinkedExport.fromJson(x))?.toList(),
-      _parts = json["parts"]?.map((x) => new UnlinkedPart.fromJson(x))?.toList();
-
   @override
-  Map<String, Object> toMap() => {
-    "names": names,
-    "exports": exports,
-    "parts": parts,
-  };
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
 
-  UnlinkedPublicNamespace.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
+  @override
+  PrelinkedReferenceKind get kind {
+    _kind ??= PrelinkedReferenceKind.values[const fb.Int32Reader().vTableGet(_bp, 1, 0)];
+    return _kind;
+  }
 
-  /**
-   * Public names defined in the compilation unit.
-   *
-   * TODO(paulberry): consider sorting these names to reduce unnecessary
-   * relinking.
-   */
-  List<UnlinkedPublicName> get names => _names ?? const <UnlinkedPublicName>[];
-
-  /**
-   * Export declarations in the compilation unit.
-   */
-  List<UnlinkedExport> get exports => _exports ?? const <UnlinkedExport>[];
-
-  /**
-   * Part declarations in the compilation unit.
-   */
-  List<UnlinkedPart> get parts => _parts ?? const <UnlinkedPart>[];
+  @override
+  int get numTypeParameters {
+    _numTypeParameters ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _numTypeParameters;
+  }
 }
 
 class UnlinkedPublicNamespaceBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedPublicNamespaceBuilder(base.BuilderContext context);
+  List<UnlinkedPublicNameBuilder> _names;
+  List<UnlinkedExportPublicBuilder> _exports;
+  List<String> _parts;
+
+  UnlinkedPublicNamespaceBuilder();
 
   /**
    * Public names defined in the compilation unit.
@@ -1819,45 +3148,61 @@
    */
   void set names(List<UnlinkedPublicNameBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("names"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["names"] = _value.map((b) => b.finish()).toList();
-    }
+    _names = _value;
   }
 
   /**
    * Export declarations in the compilation unit.
    */
-  void set exports(List<UnlinkedExportBuilder> _value) {
+  void set exports(List<UnlinkedExportPublicBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("exports"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["exports"] = _value.map((b) => b.finish()).toList();
-    }
+    _exports = _value;
   }
 
   /**
-   * Part declarations in the compilation unit.
+   * URIs referenced by part declarations in the compilation unit.
    */
-  void set parts(List<UnlinkedPartBuilder> _value) {
+  void set parts(List<String> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("parts"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["parts"] = _value.map((b) => b.finish()).toList();
-    }
+    _parts = _value;
   }
 
-  List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_names;
+    fb.Offset offset_exports;
+    fb.Offset offset_parts;
+    if (!(_names == null || _names.isEmpty)) {
+      offset_names = fbBuilder.writeList(_names.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_exports == null || _exports.isEmpty)) {
+      offset_exports = fbBuilder.writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder.writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_names != null) {
+      fbBuilder.addOffset(0, offset_names);
+    }
+    if (offset_exports != null) {
+      fbBuilder.addOffset(1, offset_exports);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(2, offset_parts);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedPublicNamespaceBuilder encodeUnlinkedPublicNamespace(base.BuilderContext builderContext, {List<UnlinkedPublicNameBuilder> names, List<UnlinkedExportBuilder> exports, List<UnlinkedPartBuilder> parts}) {
-  UnlinkedPublicNamespaceBuilder builder = new UnlinkedPublicNamespaceBuilder(builderContext);
+UnlinkedPublicNamespaceBuilder encodeUnlinkedPublicNamespace({List<UnlinkedPublicNameBuilder> names, List<UnlinkedExportPublicBuilder> exports, List<String> parts}) {
+  UnlinkedPublicNamespaceBuilder builder = new UnlinkedPublicNamespaceBuilder();
   builder.names = names;
   builder.exports = exports;
   builder.parts = parts;
@@ -1865,16 +3210,169 @@
 }
 
 /**
- * Unlinked summary information about a name referred to in one library that
- * might be defined in another.
+ * Unlinked summary information about what a compilation unit contributes to a
+ * library's public namespace.  This is the subset of [UnlinkedUnit] that is
+ * required from dependent libraries in order to perform prelinking.
  */
-class UnlinkedReference extends base.SummaryClass {
+abstract class UnlinkedPublicNamespace extends base.SummaryClass {
+  factory UnlinkedPublicNamespace.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _UnlinkedPublicNamespaceReader().read(rootRef);
+  }
+
+  /**
+   * Public names defined in the compilation unit.
+   *
+   * TODO(paulberry): consider sorting these names to reduce unnecessary
+   * relinking.
+   */
+  List<UnlinkedPublicName> get names;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportPublic> get exports;
+
+  /**
+   * URIs referenced by part declarations in the compilation unit.
+   */
+  List<String> get parts;
+}
+
+class _UnlinkedPublicNamespaceReader extends fb.TableReader<_UnlinkedPublicNamespaceImpl> {
+  const _UnlinkedPublicNamespaceReader();
+
+  @override
+  _UnlinkedPublicNamespaceImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNamespaceImpl(bp);
+}
+
+class _UnlinkedPublicNamespaceImpl implements UnlinkedPublicNamespace {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedPublicNamespaceImpl(this._bp);
+
+  List<UnlinkedPublicName> _names;
+  List<UnlinkedExportPublic> _exports;
+  List<String> _parts;
+
+  @override
+  Map<String, Object> toMap() => {
+    "names": names,
+    "exports": exports,
+    "parts": parts,
+  };
+
+  @override
+  List<UnlinkedPublicName> get names {
+    _names ??= const fb.ListReader<UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bp, 0, const <UnlinkedPublicName>[]);
+    return _names;
+  }
+
+  @override
+  List<UnlinkedExportPublic> get exports {
+    _exports ??= const fb.ListReader<UnlinkedExportPublic>(const _UnlinkedExportPublicReader()).vTableGet(_bp, 1, const <UnlinkedExportPublic>[]);
+    return _exports;
+  }
+
+  @override
+  List<String> get parts {
+    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 2, const <String>[]);
+    return _parts;
+  }
+}
+
+class UnlinkedReferenceBuilder {
+  bool _finished = false;
+
   String _name;
   int _prefixReference;
 
-  UnlinkedReference.fromJson(Map json)
-    : _name = json["name"],
-      _prefixReference = json["prefixReference"];
+  UnlinkedReferenceBuilder();
+
+  /**
+   * Name of the entity being referred to.  The empty string refers to the
+   * pseudo-type `dynamic`.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
+   * an index into [UnlinkedUnit.references].
+   *
+   * Prefix references must always point backward; that is, for all i, if
+   * UnlinkedUnit.references[i].prefixReference != 0, then
+   * UnlinkedUnit.references[i].prefixReference < i.
+   */
+  void set prefixReference(int _value) {
+    assert(!_finished);
+    _prefixReference = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_prefixReference != null && _prefixReference != 0) {
+      fbBuilder.addInt32(1, _prefixReference);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedReferenceBuilder encodeUnlinkedReference({String name, int prefixReference}) {
+  UnlinkedReferenceBuilder builder = new UnlinkedReferenceBuilder();
+  builder.name = name;
+  builder.prefixReference = prefixReference;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a name referred to in one library that
+ * might be defined in another.
+ */
+abstract class UnlinkedReference extends base.SummaryClass {
+
+  /**
+   * Name of the entity being referred to.  The empty string refers to the
+   * pseudo-type `dynamic`.
+   */
+  String get name;
+
+  /**
+   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
+   * an index into [UnlinkedUnit.references].
+   *
+   * Prefix references must always point backward; that is, for all i, if
+   * UnlinkedUnit.references[i].prefixReference != 0, then
+   * UnlinkedUnit.references[i].prefixReference < i.
+   */
+  int get prefixReference;
+}
+
+class _UnlinkedReferenceReader extends fb.TableReader<_UnlinkedReferenceImpl> {
+  const _UnlinkedReferenceReader();
+
+  @override
+  _UnlinkedReferenceImpl createObject(fb.BufferPointer bp) => new _UnlinkedReferenceImpl(bp);
+}
+
+class _UnlinkedReferenceImpl implements UnlinkedReference {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedReferenceImpl(this._bp);
+
+  String _name;
+  int _prefixReference;
 
   @override
   Map<String, Object> toMap() => {
@@ -1882,124 +3380,54 @@
     "prefixReference": prefixReference,
   };
 
-  /**
-   * Name of the entity being referred to.  The empty string refers to the
-   * pseudo-type `dynamic`.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
-   * an index into [UnlinkedUnit.references].
-   */
-  int get prefixReference => _prefixReference ?? 0;
-}
-
-class UnlinkedReferenceBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  UnlinkedReferenceBuilder(base.BuilderContext context);
-
-  /**
-   * Name of the entity being referred to.  The empty string refers to the
-   * pseudo-type `dynamic`.
-   */
-  void set name(String _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
   }
 
-  /**
-   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
-   * an index into [UnlinkedUnit.references].
-   */
-  void set prefixReference(int _value) {
-    assert(!_finished);
-    assert(!_json.containsKey("prefixReference"));
-    if (_value != null) {
-      _json["prefixReference"] = _value;
-    }
-  }
-
-  Map finish() {
-    assert(!_finished);
-    _finished = true;
-    return _json;
-  }
-}
-
-UnlinkedReferenceBuilder encodeUnlinkedReference(base.BuilderContext builderContext, {String name, int prefixReference}) {
-  UnlinkedReferenceBuilder builder = new UnlinkedReferenceBuilder(builderContext);
-  builder.name = name;
-  builder.prefixReference = prefixReference;
-  return builder;
-}
-
-/**
- * Unlinked summary information about a typedef declaration.
- */
-class UnlinkedTypedef extends base.SummaryClass {
-  String _name;
-  List<UnlinkedTypeParam> _typeParameters;
-  UnlinkedTypeRef _returnType;
-  List<UnlinkedParam> _parameters;
-
-  UnlinkedTypedef.fromJson(Map json)
-    : _name = json["name"],
-      _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
-      _returnType = json["returnType"] == null ? null : new UnlinkedTypeRef.fromJson(json["returnType"]),
-      _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList();
-
   @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "typeParameters": typeParameters,
-    "returnType": returnType,
-    "parameters": parameters,
-  };
-
-  /**
-   * Name of the typedef.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * Type parameters of the typedef, if any.
-   */
-  List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
-
-  /**
-   * Return type of the typedef.  Absent if the return type is `void`.
-   */
-  UnlinkedTypeRef get returnType => _returnType;
-
-  /**
-   * Parameters of the executable, if any.
-   */
-  List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
+  int get prefixReference {
+    _prefixReference ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _prefixReference;
+  }
 }
 
 class UnlinkedTypedefBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedTypedefBuilder(base.BuilderContext context);
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+  UnlinkedTypeRefBuilder _returnType;
+  List<UnlinkedParamBuilder> _parameters;
+
+  UnlinkedTypedefBuilder();
 
   /**
    * Name of the typedef.
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the typedef name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the typedef, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
   }
 
   /**
@@ -2007,10 +3435,7 @@
    */
   void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("typeParameters"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["typeParameters"] = _value.map((b) => b.finish()).toList();
-    }
+    _typeParameters = _value;
   }
 
   /**
@@ -2018,10 +3443,7 @@
    */
   void set returnType(UnlinkedTypeRefBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("returnType"));
-    if (_value != null) {
-      _json["returnType"] = _value.finish();
-    }
+    _returnType = _value;
   }
 
   /**
@@ -2029,22 +3451,60 @@
    */
   void set parameters(List<UnlinkedParamBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("parameters"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["parameters"] = _value.map((b) => b.finish()).toList();
-    }
+    _parameters = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_typeParameters;
+    fb.Offset offset_returnType;
+    fb.Offset offset_parameters;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder.writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_returnType != null) {
+      offset_returnType = _returnType.finish(fbBuilder);
+    }
+    if (!(_parameters == null || _parameters.isEmpty)) {
+      offset_parameters = fbBuilder.writeList(_parameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(3, offset_typeParameters);
+    }
+    if (offset_returnType != null) {
+      fbBuilder.addOffset(4, offset_returnType);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(5, offset_parameters);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedTypedefBuilder encodeUnlinkedTypedef(base.BuilderContext builderContext, {String name, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
-  UnlinkedTypedefBuilder builder = new UnlinkedTypedefBuilder(builderContext);
+UnlinkedTypedefBuilder encodeUnlinkedTypedef({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
+  UnlinkedTypedefBuilder builder = new UnlinkedTypedefBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
   builder.typeParameters = typeParameters;
   builder.returnType = returnType;
   builder.parameters = parameters;
@@ -2052,50 +3512,131 @@
 }
 
 /**
- * Unlinked summary information about a type parameter declaration.
+ * Unlinked summary information about a typedef declaration.
  */
-class UnlinkedTypeParam extends base.SummaryClass {
-  String _name;
-  UnlinkedTypeRef _bound;
+abstract class UnlinkedTypedef extends base.SummaryClass {
 
-  UnlinkedTypeParam.fromJson(Map json)
-    : _name = json["name"],
-      _bound = json["bound"] == null ? null : new UnlinkedTypeRef.fromJson(json["bound"]);
+  /**
+   * Name of the typedef.
+   */
+  String get name;
+
+  /**
+   * Offset of the typedef name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the typedef, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Type parameters of the typedef, if any.
+   */
+  List<UnlinkedTypeParam> get typeParameters;
+
+  /**
+   * Return type of the typedef.  Absent if the return type is `void`.
+   */
+  UnlinkedTypeRef get returnType;
+
+  /**
+   * Parameters of the executable, if any.
+   */
+  List<UnlinkedParam> get parameters;
+}
+
+class _UnlinkedTypedefReader extends fb.TableReader<_UnlinkedTypedefImpl> {
+  const _UnlinkedTypedefReader();
+
+  @override
+  _UnlinkedTypedefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypedefImpl(bp);
+}
+
+class _UnlinkedTypedefImpl implements UnlinkedTypedef {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedTypedefImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _returnType;
+  List<UnlinkedParam> _parameters;
 
   @override
   Map<String, Object> toMap() => {
     "name": name,
-    "bound": bound,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "returnType": returnType,
+    "parameters": parameters,
   };
 
-  /**
-   * Name of the type parameter.
-   */
-  String get name => _name ?? '';
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
 
-  /**
-   * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
-   * null.
-   */
-  UnlinkedTypeRef get bound => _bound;
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 3, const <UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+
+  @override
+  UnlinkedTypeRef get returnType {
+    _returnType ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+    return _returnType;
+  }
+
+  @override
+  List<UnlinkedParam> get parameters {
+    _parameters ??= const fb.ListReader<UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 5, const <UnlinkedParam>[]);
+    return _parameters;
+  }
 }
 
 class UnlinkedTypeParamBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedTypeParamBuilder(base.BuilderContext context);
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRefBuilder _bound;
+
+  UnlinkedTypeParamBuilder();
 
   /**
    * Name of the type parameter.
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the type parameter name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
   }
 
   /**
@@ -2104,92 +3645,114 @@
    */
   void set bound(UnlinkedTypeRefBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("bound"));
-    if (_value != null) {
-      _json["bound"] = _value.finish();
-    }
+    _bound = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_bound;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_bound != null) {
+      offset_bound = _bound.finish(fbBuilder);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_bound != null) {
+      fbBuilder.addOffset(2, offset_bound);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedTypeParamBuilder encodeUnlinkedTypeParam(base.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder bound}) {
-  UnlinkedTypeParamBuilder builder = new UnlinkedTypeParamBuilder(builderContext);
+UnlinkedTypeParamBuilder encodeUnlinkedTypeParam({String name, int nameOffset, UnlinkedTypeRefBuilder bound}) {
+  UnlinkedTypeParamBuilder builder = new UnlinkedTypeParamBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
   builder.bound = bound;
   return builder;
 }
 
 /**
- * Unlinked summary information about a reference to a type.
+ * Unlinked summary information about a type parameter declaration.
  */
-class UnlinkedTypeRef extends base.SummaryClass {
-  int _reference;
-  int _paramReference;
-  List<UnlinkedTypeRef> _typeArguments;
+abstract class UnlinkedTypeParam extends base.SummaryClass {
 
-  UnlinkedTypeRef.fromJson(Map json)
-    : _reference = json["reference"],
-      _paramReference = json["paramReference"],
-      _typeArguments = json["typeArguments"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList();
+  /**
+   * Name of the type parameter.
+   */
+  String get name;
+
+  /**
+   * Offset of the type parameter name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
+   * null.
+   */
+  UnlinkedTypeRef get bound;
+}
+
+class _UnlinkedTypeParamReader extends fb.TableReader<_UnlinkedTypeParamImpl> {
+  const _UnlinkedTypeParamReader();
+
+  @override
+  _UnlinkedTypeParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeParamImpl(bp);
+}
+
+class _UnlinkedTypeParamImpl implements UnlinkedTypeParam {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedTypeParamImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRef _bound;
 
   @override
   Map<String, Object> toMap() => {
-    "reference": reference,
-    "paramReference": paramReference,
-    "typeArguments": typeArguments,
+    "name": name,
+    "nameOffset": nameOffset,
+    "bound": bound,
   };
 
-  /**
-   * Index into [UnlinkedUnit.references] for the type being referred to, or
-   * zero if this is a reference to a type parameter.
-   *
-   * Note that since zero is also a valid index into
-   * [UnlinkedUnit.references], we cannot distinguish between references to
-   * type parameters and references to types by checking [reference] against
-   * zero.  To distinguish between references to type parameters and references
-   * to types, check whether [paramReference] is zero.
-   */
-  int get reference => _reference ?? 0;
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
 
-  /**
-   * If this is a reference to a type parameter, one-based index into the list
-   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
-   * Bruijn index conventions; that is, innermost parameters come first, and
-   * if a class or method has multiple parameters, they are indexed from right
-   * to left.  So for instance, if the enclosing declaration is
-   *
-   *     class C<T,U> {
-   *       m<V,W> {
-   *         ...
-   *       }
-   *     }
-   *
-   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
-   * respectively.
-   *
-   * If the type being referred to is not a type parameter, [paramReference] is
-   * zero.
-   */
-  int get paramReference => _paramReference ?? 0;
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
 
-  /**
-   * If this is an instantiation of a generic type, the type arguments used to
-   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
-   */
-  List<UnlinkedTypeRef> get typeArguments => _typeArguments ?? const <UnlinkedTypeRef>[];
+  @override
+  UnlinkedTypeRef get bound {
+    _bound ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 2, null);
+    return _bound;
+  }
 }
 
 class UnlinkedTypeRefBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedTypeRefBuilder(base.BuilderContext context);
+  int _reference;
+  int _paramReference;
+  List<UnlinkedTypeRefBuilder> _typeArguments;
+
+  UnlinkedTypeRefBuilder();
 
   /**
    * Index into [UnlinkedUnit.references] for the type being referred to, or
@@ -2203,10 +3766,7 @@
    */
   void set reference(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("reference"));
-    if (_value != null) {
-      _json["reference"] = _value;
-    }
+    _reference = _value;
   }
 
   /**
@@ -2230,10 +3790,7 @@
    */
   void set paramReference(int _value) {
     assert(!_finished);
-    assert(!_json.containsKey("paramReference"));
-    if (_value != null) {
-      _json["paramReference"] = _value;
-    }
+    _paramReference = _value;
   }
 
   /**
@@ -2242,21 +3799,32 @@
    */
   void set typeArguments(List<UnlinkedTypeRefBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("typeArguments"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["typeArguments"] = _value.map((b) => b.finish()).toList();
-    }
+    _typeArguments = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_typeArguments;
+    if (!(_typeArguments == null || _typeArguments.isEmpty)) {
+      offset_typeArguments = fbBuilder.writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (_reference != null && _reference != 0) {
+      fbBuilder.addInt32(0, _reference);
+    }
+    if (_paramReference != null && _paramReference != 0) {
+      fbBuilder.addInt32(1, _paramReference);
+    }
+    if (offset_typeArguments != null) {
+      fbBuilder.addOffset(2, offset_typeArguments);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedTypeRefBuilder encodeUnlinkedTypeRef(base.BuilderContext builderContext, {int reference, int paramReference, List<UnlinkedTypeRefBuilder> typeArguments}) {
-  UnlinkedTypeRefBuilder builder = new UnlinkedTypeRefBuilder(builderContext);
+UnlinkedTypeRefBuilder encodeUnlinkedTypeRef({int reference, int paramReference, List<UnlinkedTypeRefBuilder> typeArguments}) {
+  UnlinkedTypeRefBuilder builder = new UnlinkedTypeRefBuilder();
   builder.reference = reference;
   builder.paramReference = paramReference;
   builder.typeArguments = typeArguments;
@@ -2264,110 +3832,145 @@
 }
 
 /**
- * Unlinked summary information about a compilation unit ("part file").
+ * Unlinked summary information about a reference to a type.
  */
-class UnlinkedUnit extends base.SummaryClass {
-  String _libraryName;
-  UnlinkedPublicNamespace _publicNamespace;
-  List<UnlinkedReference> _references;
-  List<UnlinkedClass> _classes;
-  List<UnlinkedEnum> _enums;
-  List<UnlinkedExecutable> _executables;
-  List<UnlinkedImport> _imports;
-  List<UnlinkedTypedef> _typedefs;
-  List<UnlinkedVariable> _variables;
+abstract class UnlinkedTypeRef extends base.SummaryClass {
 
-  UnlinkedUnit.fromJson(Map json)
-    : _libraryName = json["libraryName"],
-      _publicNamespace = json["publicNamespace"] == null ? null : new UnlinkedPublicNamespace.fromJson(json["publicNamespace"]),
-      _references = json["references"]?.map((x) => new UnlinkedReference.fromJson(x))?.toList(),
-      _classes = json["classes"]?.map((x) => new UnlinkedClass.fromJson(x))?.toList(),
-      _enums = json["enums"]?.map((x) => new UnlinkedEnum.fromJson(x))?.toList(),
-      _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
-      _imports = json["imports"]?.map((x) => new UnlinkedImport.fromJson(x))?.toList(),
-      _typedefs = json["typedefs"]?.map((x) => new UnlinkedTypedef.fromJson(x))?.toList(),
-      _variables = json["variables"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList();
+  /**
+   * Index into [UnlinkedUnit.references] for the type being referred to, or
+   * zero if this is a reference to a type parameter.
+   *
+   * Note that since zero is also a valid index into
+   * [UnlinkedUnit.references], we cannot distinguish between references to
+   * type parameters and references to types by checking [reference] against
+   * zero.  To distinguish between references to type parameters and references
+   * to types, check whether [paramReference] is zero.
+   */
+  int get reference;
+
+  /**
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
+   *
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
+   */
+  int get paramReference;
+
+  /**
+   * If this is an instantiation of a generic type, the type arguments used to
+   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
+   */
+  List<UnlinkedTypeRef> get typeArguments;
+}
+
+class _UnlinkedTypeRefReader extends fb.TableReader<_UnlinkedTypeRefImpl> {
+  const _UnlinkedTypeRefReader();
+
+  @override
+  _UnlinkedTypeRefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeRefImpl(bp);
+}
+
+class _UnlinkedTypeRefImpl implements UnlinkedTypeRef {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedTypeRefImpl(this._bp);
+
+  int _reference;
+  int _paramReference;
+  List<UnlinkedTypeRef> _typeArguments;
 
   @override
   Map<String, Object> toMap() => {
-    "libraryName": libraryName,
-    "publicNamespace": publicNamespace,
-    "references": references,
-    "classes": classes,
-    "enums": enums,
-    "executables": executables,
-    "imports": imports,
-    "typedefs": typedefs,
-    "variables": variables,
+    "reference": reference,
+    "paramReference": paramReference,
+    "typeArguments": typeArguments,
   };
 
-  UnlinkedUnit.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
+  @override
+  int get reference {
+    _reference ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _reference;
+  }
 
-  /**
-   * Name of the library (from a "library" declaration, if present).
-   */
-  String get libraryName => _libraryName ?? '';
+  @override
+  int get paramReference {
+    _paramReference ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _paramReference;
+  }
 
-  /**
-   * Unlinked public namespace of this compilation unit.
-   */
-  UnlinkedPublicNamespace get publicNamespace => _publicNamespace;
-
-  /**
-   * Top level and prefixed names referred to by this compilation unit.  The
-   * zeroth element of this array is always populated and always represents a
-   * reference to the pseudo-type "dynamic".
-   */
-  List<UnlinkedReference> get references => _references ?? const <UnlinkedReference>[];
-
-  /**
-   * Classes declared in the compilation unit.
-   */
-  List<UnlinkedClass> get classes => _classes ?? const <UnlinkedClass>[];
-
-  /**
-   * Enums declared in the compilation unit.
-   */
-  List<UnlinkedEnum> get enums => _enums ?? const <UnlinkedEnum>[];
-
-  /**
-   * Top level executable objects (functions, getters, and setters) declared in
-   * the compilation unit.
-   */
-  List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
-
-  /**
-   * Import declarations in the compilation unit.
-   */
-  List<UnlinkedImport> get imports => _imports ?? const <UnlinkedImport>[];
-
-  /**
-   * Typedefs declared in the compilation unit.
-   */
-  List<UnlinkedTypedef> get typedefs => _typedefs ?? const <UnlinkedTypedef>[];
-
-  /**
-   * Top level variables declared in the compilation unit.
-   */
-  List<UnlinkedVariable> get variables => _variables ?? const <UnlinkedVariable>[];
+  @override
+  List<UnlinkedTypeRef> get typeArguments {
+    _typeArguments ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 2, const <UnlinkedTypeRef>[]);
+    return _typeArguments;
+  }
 }
 
 class UnlinkedUnitBuilder {
-  final Map _json = {};
-
   bool _finished = false;
 
-  UnlinkedUnitBuilder(base.BuilderContext context);
+  String _libraryName;
+  int _libraryNameOffset;
+  int _libraryNameLength;
+  UnlinkedDocumentationCommentBuilder _libraryDocumentationComment;
+  UnlinkedPublicNamespaceBuilder _publicNamespace;
+  List<UnlinkedReferenceBuilder> _references;
+  List<UnlinkedClassBuilder> _classes;
+  List<UnlinkedEnumBuilder> _enums;
+  List<UnlinkedExecutableBuilder> _executables;
+  List<UnlinkedExportNonPublicBuilder> _exports;
+  List<UnlinkedImportBuilder> _imports;
+  List<UnlinkedPartBuilder> _parts;
+  List<UnlinkedTypedefBuilder> _typedefs;
+  List<UnlinkedVariableBuilder> _variables;
+
+  UnlinkedUnitBuilder();
 
   /**
    * Name of the library (from a "library" declaration, if present).
    */
   void set libraryName(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("libraryName"));
-    if (_value != null) {
-      _json["libraryName"] = _value;
-    }
+    _libraryName = _value;
+  }
+
+  /**
+   * Offset of the library name relative to the beginning of the file (or 0 if
+   * the library has no name).
+   */
+  void set libraryNameOffset(int _value) {
+    assert(!_finished);
+    _libraryNameOffset = _value;
+  }
+
+  /**
+   * Length of the library name as it appears in the source code (or 0 if the
+   * library has no name).
+   */
+  void set libraryNameLength(int _value) {
+    assert(!_finished);
+    _libraryNameLength = _value;
+  }
+
+  /**
+   * Documentation comment for the library, or `null` if there is no
+   * documentation comment.
+   */
+  void set libraryDocumentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _libraryDocumentationComment = _value;
   }
 
   /**
@@ -2375,10 +3978,7 @@
    */
   void set publicNamespace(UnlinkedPublicNamespaceBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("publicNamespace"));
-    if (_value != null) {
-      _json["publicNamespace"] = _value.finish();
-    }
+    _publicNamespace = _value;
   }
 
   /**
@@ -2388,10 +3988,7 @@
    */
   void set references(List<UnlinkedReferenceBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("references"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["references"] = _value.map((b) => b.finish()).toList();
-    }
+    _references = _value;
   }
 
   /**
@@ -2399,10 +3996,7 @@
    */
   void set classes(List<UnlinkedClassBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("classes"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["classes"] = _value.map((b) => b.finish()).toList();
-    }
+    _classes = _value;
   }
 
   /**
@@ -2410,10 +4004,7 @@
    */
   void set enums(List<UnlinkedEnumBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("enums"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["enums"] = _value.map((b) => b.finish()).toList();
-    }
+    _enums = _value;
   }
 
   /**
@@ -2422,10 +4013,15 @@
    */
   void set executables(List<UnlinkedExecutableBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("executables"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["executables"] = _value.map((b) => b.finish()).toList();
-    }
+    _executables = _value;
+  }
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  void set exports(List<UnlinkedExportNonPublicBuilder> _value) {
+    assert(!_finished);
+    _exports = _value;
   }
 
   /**
@@ -2433,10 +4029,15 @@
    */
   void set imports(List<UnlinkedImportBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("imports"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["imports"] = _value.map((b) => b.finish()).toList();
-    }
+    _imports = _value;
+  }
+
+  /**
+   * Part declarations in the compilation unit.
+   */
+  void set parts(List<UnlinkedPartBuilder> _value) {
+    assert(!_finished);
+    _parts = _value;
   }
 
   /**
@@ -2444,10 +4045,7 @@
    */
   void set typedefs(List<UnlinkedTypedefBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("typedefs"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["typedefs"] = _value.map((b) => b.finish()).toList();
-    }
+    _typedefs = _value;
   }
 
   /**
@@ -2455,117 +4053,384 @@
    */
   void set variables(List<UnlinkedVariableBuilder> _value) {
     assert(!_finished);
-    assert(!_json.containsKey("variables"));
-    if (!(_value == null || _value.isEmpty)) {
-      _json["variables"] = _value.map((b) => b.finish()).toList();
-    }
+    _variables = _value;
   }
 
-  List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_libraryName;
+    fb.Offset offset_libraryDocumentationComment;
+    fb.Offset offset_publicNamespace;
+    fb.Offset offset_references;
+    fb.Offset offset_classes;
+    fb.Offset offset_enums;
+    fb.Offset offset_executables;
+    fb.Offset offset_exports;
+    fb.Offset offset_imports;
+    fb.Offset offset_parts;
+    fb.Offset offset_typedefs;
+    fb.Offset offset_variables;
+    if (_libraryName != null) {
+      offset_libraryName = fbBuilder.writeString(_libraryName);
+    }
+    if (_libraryDocumentationComment != null) {
+      offset_libraryDocumentationComment = _libraryDocumentationComment.finish(fbBuilder);
+    }
+    if (_publicNamespace != null) {
+      offset_publicNamespace = _publicNamespace.finish(fbBuilder);
+    }
+    if (!(_references == null || _references.isEmpty)) {
+      offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_classes == null || _classes.isEmpty)) {
+      offset_classes = fbBuilder.writeList(_classes.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_enums == null || _enums.isEmpty)) {
+      offset_enums = fbBuilder.writeList(_enums.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_executables == null || _executables.isEmpty)) {
+      offset_executables = fbBuilder.writeList(_executables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_exports == null || _exports.isEmpty)) {
+      offset_exports = fbBuilder.writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_imports == null || _imports.isEmpty)) {
+      offset_imports = fbBuilder.writeList(_imports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder.writeList(_parts.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_typedefs == null || _typedefs.isEmpty)) {
+      offset_typedefs = fbBuilder.writeList(_typedefs.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_variables == null || _variables.isEmpty)) {
+      offset_variables = fbBuilder.writeList(_variables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_libraryName != null) {
+      fbBuilder.addOffset(0, offset_libraryName);
+    }
+    if (_libraryNameOffset != null && _libraryNameOffset != 0) {
+      fbBuilder.addInt32(1, _libraryNameOffset);
+    }
+    if (_libraryNameLength != null && _libraryNameLength != 0) {
+      fbBuilder.addInt32(2, _libraryNameLength);
+    }
+    if (offset_libraryDocumentationComment != null) {
+      fbBuilder.addOffset(3, offset_libraryDocumentationComment);
+    }
+    if (offset_publicNamespace != null) {
+      fbBuilder.addOffset(4, offset_publicNamespace);
+    }
+    if (offset_references != null) {
+      fbBuilder.addOffset(5, offset_references);
+    }
+    if (offset_classes != null) {
+      fbBuilder.addOffset(6, offset_classes);
+    }
+    if (offset_enums != null) {
+      fbBuilder.addOffset(7, offset_enums);
+    }
+    if (offset_executables != null) {
+      fbBuilder.addOffset(8, offset_executables);
+    }
+    if (offset_exports != null) {
+      fbBuilder.addOffset(9, offset_exports);
+    }
+    if (offset_imports != null) {
+      fbBuilder.addOffset(10, offset_imports);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(11, offset_parts);
+    }
+    if (offset_typedefs != null) {
+      fbBuilder.addOffset(12, offset_typedefs);
+    }
+    if (offset_variables != null) {
+      fbBuilder.addOffset(13, offset_variables);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedUnitBuilder encodeUnlinkedUnit(base.BuilderContext builderContext, {String libraryName, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedImportBuilder> imports, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables}) {
-  UnlinkedUnitBuilder builder = new UnlinkedUnitBuilder(builderContext);
+UnlinkedUnitBuilder encodeUnlinkedUnit({String libraryName, int libraryNameOffset, int libraryNameLength, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedPartBuilder> parts, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables}) {
+  UnlinkedUnitBuilder builder = new UnlinkedUnitBuilder();
   builder.libraryName = libraryName;
+  builder.libraryNameOffset = libraryNameOffset;
+  builder.libraryNameLength = libraryNameLength;
+  builder.libraryDocumentationComment = libraryDocumentationComment;
   builder.publicNamespace = publicNamespace;
   builder.references = references;
   builder.classes = classes;
   builder.enums = enums;
   builder.executables = executables;
+  builder.exports = exports;
   builder.imports = imports;
+  builder.parts = parts;
   builder.typedefs = typedefs;
   builder.variables = variables;
   return builder;
 }
 
 /**
- * Unlinked summary information about a top level variable, local variable, or
- * a field.
+ * Unlinked summary information about a compilation unit ("part file").
  */
-class UnlinkedVariable extends base.SummaryClass {
+abstract class UnlinkedUnit extends base.SummaryClass {
+  factory UnlinkedUnit.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _UnlinkedUnitReader().read(rootRef);
+  }
+
+  /**
+   * Name of the library (from a "library" declaration, if present).
+   */
+  String get libraryName;
+
+  /**
+   * Offset of the library name relative to the beginning of the file (or 0 if
+   * the library has no name).
+   */
+  int get libraryNameOffset;
+
+  /**
+   * Length of the library name as it appears in the source code (or 0 if the
+   * library has no name).
+   */
+  int get libraryNameLength;
+
+  /**
+   * Documentation comment for the library, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get libraryDocumentationComment;
+
+  /**
+   * Unlinked public namespace of this compilation unit.
+   */
+  UnlinkedPublicNamespace get publicNamespace;
+
+  /**
+   * Top level and prefixed names referred to by this compilation unit.  The
+   * zeroth element of this array is always populated and always represents a
+   * reference to the pseudo-type "dynamic".
+   */
+  List<UnlinkedReference> get references;
+
+  /**
+   * Classes declared in the compilation unit.
+   */
+  List<UnlinkedClass> get classes;
+
+  /**
+   * Enums declared in the compilation unit.
+   */
+  List<UnlinkedEnum> get enums;
+
+  /**
+   * Top level executable objects (functions, getters, and setters) declared in
+   * the compilation unit.
+   */
+  List<UnlinkedExecutable> get executables;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportNonPublic> get exports;
+
+  /**
+   * Import declarations in the compilation unit.
+   */
+  List<UnlinkedImport> get imports;
+
+  /**
+   * Part declarations in the compilation unit.
+   */
+  List<UnlinkedPart> get parts;
+
+  /**
+   * Typedefs declared in the compilation unit.
+   */
+  List<UnlinkedTypedef> get typedefs;
+
+  /**
+   * Top level variables declared in the compilation unit.
+   */
+  List<UnlinkedVariable> get variables;
+}
+
+class _UnlinkedUnitReader extends fb.TableReader<_UnlinkedUnitImpl> {
+  const _UnlinkedUnitReader();
+
+  @override
+  _UnlinkedUnitImpl createObject(fb.BufferPointer bp) => new _UnlinkedUnitImpl(bp);
+}
+
+class _UnlinkedUnitImpl implements UnlinkedUnit {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedUnitImpl(this._bp);
+
+  String _libraryName;
+  int _libraryNameOffset;
+  int _libraryNameLength;
+  UnlinkedDocumentationComment _libraryDocumentationComment;
+  UnlinkedPublicNamespace _publicNamespace;
+  List<UnlinkedReference> _references;
+  List<UnlinkedClass> _classes;
+  List<UnlinkedEnum> _enums;
+  List<UnlinkedExecutable> _executables;
+  List<UnlinkedExportNonPublic> _exports;
+  List<UnlinkedImport> _imports;
+  List<UnlinkedPart> _parts;
+  List<UnlinkedTypedef> _typedefs;
+  List<UnlinkedVariable> _variables;
+
+  @override
+  Map<String, Object> toMap() => {
+    "libraryName": libraryName,
+    "libraryNameOffset": libraryNameOffset,
+    "libraryNameLength": libraryNameLength,
+    "libraryDocumentationComment": libraryDocumentationComment,
+    "publicNamespace": publicNamespace,
+    "references": references,
+    "classes": classes,
+    "enums": enums,
+    "executables": executables,
+    "exports": exports,
+    "imports": imports,
+    "parts": parts,
+    "typedefs": typedefs,
+    "variables": variables,
+  };
+
+  @override
+  String get libraryName {
+    _libraryName ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _libraryName;
+  }
+
+  @override
+  int get libraryNameOffset {
+    _libraryNameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _libraryNameOffset;
+  }
+
+  @override
+  int get libraryNameLength {
+    _libraryNameLength ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _libraryNameLength;
+  }
+
+  @override
+  UnlinkedDocumentationComment get libraryDocumentationComment {
+    _libraryDocumentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 3, null);
+    return _libraryDocumentationComment;
+  }
+
+  @override
+  UnlinkedPublicNamespace get publicNamespace {
+    _publicNamespace ??= const _UnlinkedPublicNamespaceReader().vTableGet(_bp, 4, null);
+    return _publicNamespace;
+  }
+
+  @override
+  List<UnlinkedReference> get references {
+    _references ??= const fb.ListReader<UnlinkedReference>(const _UnlinkedReferenceReader()).vTableGet(_bp, 5, const <UnlinkedReference>[]);
+    return _references;
+  }
+
+  @override
+  List<UnlinkedClass> get classes {
+    _classes ??= const fb.ListReader<UnlinkedClass>(const _UnlinkedClassReader()).vTableGet(_bp, 6, const <UnlinkedClass>[]);
+    return _classes;
+  }
+
+  @override
+  List<UnlinkedEnum> get enums {
+    _enums ??= const fb.ListReader<UnlinkedEnum>(const _UnlinkedEnumReader()).vTableGet(_bp, 7, const <UnlinkedEnum>[]);
+    return _enums;
+  }
+
+  @override
+  List<UnlinkedExecutable> get executables {
+    _executables ??= const fb.ListReader<UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 8, const <UnlinkedExecutable>[]);
+    return _executables;
+  }
+
+  @override
+  List<UnlinkedExportNonPublic> get exports {
+    _exports ??= const fb.ListReader<UnlinkedExportNonPublic>(const _UnlinkedExportNonPublicReader()).vTableGet(_bp, 9, const <UnlinkedExportNonPublic>[]);
+    return _exports;
+  }
+
+  @override
+  List<UnlinkedImport> get imports {
+    _imports ??= const fb.ListReader<UnlinkedImport>(const _UnlinkedImportReader()).vTableGet(_bp, 10, const <UnlinkedImport>[]);
+    return _imports;
+  }
+
+  @override
+  List<UnlinkedPart> get parts {
+    _parts ??= const fb.ListReader<UnlinkedPart>(const _UnlinkedPartReader()).vTableGet(_bp, 11, const <UnlinkedPart>[]);
+    return _parts;
+  }
+
+  @override
+  List<UnlinkedTypedef> get typedefs {
+    _typedefs ??= const fb.ListReader<UnlinkedTypedef>(const _UnlinkedTypedefReader()).vTableGet(_bp, 12, const <UnlinkedTypedef>[]);
+    return _typedefs;
+  }
+
+  @override
+  List<UnlinkedVariable> get variables {
+    _variables ??= const fb.ListReader<UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 13, const <UnlinkedVariable>[]);
+    return _variables;
+  }
+}
+
+class UnlinkedVariableBuilder {
+  bool _finished = false;
+
   String _name;
-  UnlinkedTypeRef _type;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  UnlinkedTypeRefBuilder _type;
   bool _isStatic;
   bool _isFinal;
   bool _isConst;
   bool _hasImplicitType;
 
-  UnlinkedVariable.fromJson(Map json)
-    : _name = json["name"],
-      _type = json["type"] == null ? null : new UnlinkedTypeRef.fromJson(json["type"]),
-      _isStatic = json["isStatic"],
-      _isFinal = json["isFinal"],
-      _isConst = json["isConst"],
-      _hasImplicitType = json["hasImplicitType"];
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "type": type,
-    "isStatic": isStatic,
-    "isFinal": isFinal,
-    "isConst": isConst,
-    "hasImplicitType": hasImplicitType,
-  };
-
-  /**
-   * Name of the variable.
-   */
-  String get name => _name ?? '';
-
-  /**
-   * Declared type of the variable.  Note that when strong mode is enabled, the
-   * actual type of the variable may be different due to type inference.
-   */
-  UnlinkedTypeRef get type => _type;
-
-  /**
-   * Indicates whether the variable is declared using the `static` keyword.
-   *
-   * Note that for top level variables, this flag is false, since they are not
-   * declared using the `static` keyword (even though they are considered
-   * static for semantic purposes).
-   */
-  bool get isStatic => _isStatic ?? false;
-
-  /**
-   * Indicates whether the variable is declared using the `final` keyword.
-   */
-  bool get isFinal => _isFinal ?? false;
-
-  /**
-   * Indicates whether the variable is declared using the `const` keyword.
-   */
-  bool get isConst => _isConst ?? false;
-
-  /**
-   * Indicates whether this variable lacks an explicit type declaration.
-   */
-  bool get hasImplicitType => _hasImplicitType ?? false;
-}
-
-class UnlinkedVariableBuilder {
-  final Map _json = {};
-
-  bool _finished = false;
-
-  UnlinkedVariableBuilder(base.BuilderContext context);
+  UnlinkedVariableBuilder();
 
   /**
    * Name of the variable.
    */
   void set name(String _value) {
     assert(!_finished);
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
+    _name = _value;
+  }
+
+  /**
+   * Offset of the variable name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the variable, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
   }
 
   /**
@@ -2574,10 +4439,7 @@
    */
   void set type(UnlinkedTypeRefBuilder _value) {
     assert(!_finished);
-    assert(!_json.containsKey("type"));
-    if (_value != null) {
-      _json["type"] = _value.finish();
-    }
+    _type = _value;
   }
 
   /**
@@ -2589,10 +4451,7 @@
    */
   void set isStatic(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isStatic"));
-    if (_value != null) {
-      _json["isStatic"] = _value;
-    }
+    _isStatic = _value;
   }
 
   /**
@@ -2600,10 +4459,7 @@
    */
   void set isFinal(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isFinal"));
-    if (_value != null) {
-      _json["isFinal"] = _value;
-    }
+    _isFinal = _value;
   }
 
   /**
@@ -2611,10 +4467,7 @@
    */
   void set isConst(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("isConst"));
-    if (_value != null) {
-      _json["isConst"] = _value;
-    }
+    _isConst = _value;
   }
 
   /**
@@ -2622,22 +4475,58 @@
    */
   void set hasImplicitType(bool _value) {
     assert(!_finished);
-    assert(!_json.containsKey("hasImplicitType"));
-    if (_value != null) {
-      _json["hasImplicitType"] = _value;
-    }
+    _hasImplicitType = _value;
   }
 
-  Map finish() {
+  fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    return _json;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_type;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (_type != null) {
+      offset_type = _type.finish(fbBuilder);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_type != null) {
+      fbBuilder.addOffset(3, offset_type);
+    }
+    if (_isStatic == true) {
+      fbBuilder.addBool(4, true);
+    }
+    if (_isFinal == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_isConst == true) {
+      fbBuilder.addBool(6, true);
+    }
+    if (_hasImplicitType == true) {
+      fbBuilder.addBool(7, true);
+    }
+    return fbBuilder.endTable();
   }
 }
 
-UnlinkedVariableBuilder encodeUnlinkedVariable(base.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst, bool hasImplicitType}) {
-  UnlinkedVariableBuilder builder = new UnlinkedVariableBuilder(builderContext);
+UnlinkedVariableBuilder encodeUnlinkedVariable({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst, bool hasImplicitType}) {
+  UnlinkedVariableBuilder builder = new UnlinkedVariableBuilder();
   builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
   builder.type = type;
   builder.isStatic = isStatic;
   builder.isFinal = isFinal;
@@ -2646,3 +4535,138 @@
   return builder;
 }
 
+/**
+ * Unlinked summary information about a top level variable, local variable, or
+ * a field.
+ */
+abstract class UnlinkedVariable extends base.SummaryClass {
+
+  /**
+   * Name of the variable.
+   */
+  String get name;
+
+  /**
+   * Offset of the variable name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the variable, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Declared type of the variable.  Note that when strong mode is enabled, the
+   * actual type of the variable may be different due to type inference.
+   */
+  UnlinkedTypeRef get type;
+
+  /**
+   * Indicates whether the variable is declared using the `static` keyword.
+   *
+   * Note that for top level variables, this flag is false, since they are not
+   * declared using the `static` keyword (even though they are considered
+   * static for semantic purposes).
+   */
+  bool get isStatic;
+
+  /**
+   * Indicates whether the variable is declared using the `final` keyword.
+   */
+  bool get isFinal;
+
+  /**
+   * Indicates whether the variable is declared using the `const` keyword.
+   */
+  bool get isConst;
+
+  /**
+   * Indicates whether this variable lacks an explicit type declaration.
+   */
+  bool get hasImplicitType;
+}
+
+class _UnlinkedVariableReader extends fb.TableReader<_UnlinkedVariableImpl> {
+  const _UnlinkedVariableReader();
+
+  @override
+  _UnlinkedVariableImpl createObject(fb.BufferPointer bp) => new _UnlinkedVariableImpl(bp);
+}
+
+class _UnlinkedVariableImpl implements UnlinkedVariable {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedVariableImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  UnlinkedTypeRef _type;
+  bool _isStatic;
+  bool _isFinal;
+  bool _isConst;
+  bool _hasImplicitType;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "type": type,
+    "isStatic": isStatic,
+    "isFinal": isFinal,
+    "isConst": isConst,
+    "hasImplicitType": hasImplicitType,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  UnlinkedTypeRef get type {
+    _type ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 3, null);
+    return _type;
+  }
+
+  @override
+  bool get isStatic {
+    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 4, false);
+    return _isStatic;
+  }
+
+  @override
+  bool get isFinal {
+    _isFinal ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isFinal;
+  }
+
+  @override
+  bool get isConst {
+    _isConst ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    return _isConst;
+  }
+
+  @override
+  bool get hasImplicitType {
+    _hasImplicitType ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    return _hasImplicitType;
+  }
+}
+
diff --git a/pkg/analyzer/lib/src/summary/name_filter.dart b/pkg/analyzer/lib/src/summary/name_filter.dart
new file mode 100644
index 0000000..7b130ec
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/name_filter.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2016, 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.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * A [NameFilter] represents the set of filtering rules implied by zero or more
+ * combinators in an `export` or `import` statement.
+ */
+class NameFilter {
+  /**
+   * A [NameFilter] representing no filtering at all (i.e. no combinators).
+   */
+  static final NameFilter identity =
+      new NameFilter._(hiddenNames: new Set<String>());
+
+  /**
+   * If this [NameFilter] accepts a finite number of names and hides all
+   * others, the (possibly empty) set of names it accepts.  Otherwise `null`.
+   */
+  final Set<String> shownNames;
+
+  /**
+   * If [shownNames] is `null`, the (possibly empty) set of names not accepted
+   * by this filter (all other names are accepted).  If [shownNames] is not
+   * `null`, then [hiddenNames] will be `null`.
+   */
+  final Set<String> hiddenNames;
+
+  /**
+   * Create a [NameFilter] based on the given [combinator].
+   */
+  factory NameFilter.forNamespaceCombinator(NamespaceCombinator combinator) {
+    if (combinator is ShowElementCombinator) {
+      return new NameFilter._(shownNames: combinator.shownNames.toSet());
+    } else if (combinator is HideElementCombinator) {
+      return new NameFilter._(hiddenNames: combinator.hiddenNames.toSet());
+    } else {
+      throw new StateError(
+          'Unexpected combinator type ${combinator.runtimeType}');
+    }
+  }
+
+  /**
+   * Create a [NameFilter] based on the given (possibly empty) sequence of
+   * [combinators].
+   */
+  factory NameFilter.forNamespaceCombinators(
+      List<NamespaceCombinator> combinators) {
+    NameFilter result = identity;
+    for (NamespaceCombinator combinator in combinators) {
+      result = result.merge(new NameFilter.forNamespaceCombinator(combinator));
+    }
+    return result;
+  }
+
+  /**
+   * Create a [NameFilter] based on the given [combinator].
+   */
+  factory NameFilter.forUnlinkedCombinator(UnlinkedCombinator combinator) {
+    if (combinator.shows.isNotEmpty) {
+      return new NameFilter._(shownNames: combinator.shows.toSet());
+    } else {
+      return new NameFilter._(hiddenNames: combinator.hides.toSet());
+    }
+  }
+
+  /**
+   * Create a [NameFilter] based on the given (possibly empty) sequence of
+   * [combinators].
+   */
+  factory NameFilter.forUnlinkedCombinators(
+      List<UnlinkedCombinator> combinators) {
+    NameFilter result = identity;
+    for (UnlinkedCombinator combinator in combinators) {
+      result = result.merge(new NameFilter.forUnlinkedCombinator(combinator));
+    }
+    return result;
+  }
+
+  const NameFilter._({this.shownNames, this.hiddenNames});
+
+  /**
+   * Determine if the given [name] is accepted by this [NameFilter].
+   */
+  bool accepts(String name) {
+    if (name.endsWith('=')) {
+      name = name.substring(0, name.length - 1);
+    }
+    if (shownNames != null) {
+      return shownNames.contains(name);
+    } else {
+      return !hiddenNames.contains(name);
+    }
+  }
+
+  /**
+   * Produce a new [NameFilter] by combining this [NameFilter] with another
+   * one.  The new [NameFilter] will only accept names that would be accepted
+   * by both input filters.
+   */
+  NameFilter merge(NameFilter other) {
+    if (shownNames != null) {
+      if (other.shownNames != null) {
+        return new NameFilter._(
+            shownNames: shownNames.intersection(other.shownNames));
+      } else {
+        return new NameFilter._(
+            shownNames: shownNames.difference(other.hiddenNames));
+      }
+    } else {
+      if (other.shownNames != null) {
+        return new NameFilter._(
+            shownNames: other.shownNames.difference(hiddenNames));
+      } else {
+        return new NameFilter._(
+            hiddenNames: hiddenNames.union(other.hiddenNames));
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
new file mode 100644
index 0000000..ad4834f
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -0,0 +1,418 @@
+// Copyright (c) 2016, 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.
+
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/name_filter.dart';
+
+/**
+ * Create a [PrelinkedLibraryBuilder] corresponding to the given
+ * [definingUnit], which should be the defining compilation unit for a library.
+ * Compilation units referenced by the defining compilation unit via `part`
+ * declarations will be retrieved using [getPart].  Public namespaces for
+ * libraries referenced by the defining compilation unit via `import`
+ * declarations (and files reachable from them via `part` and `export`
+ * declarations) will be retrieved using [getImport].
+ */
+PrelinkedLibraryBuilder prelink(UnlinkedUnit definingUnit,
+    GetPartCallback getPart, GetImportCallback getImport) {
+  return new _Prelinker(definingUnit, getPart, getImport).prelink();
+}
+
+/**
+ * Type of the callback used by the prelinker to obtain public namespace
+ * information about libraries imported by the library to be prelinked (and
+ * the transitive closure of parts and exports reachable from those libraries).
+ * [relativeUri] should be interpreted relative to the defining compilation
+ * unit of the library being prelinked.
+ *
+ * If no file exists at the given uri, `null` should be returned.
+ */
+typedef UnlinkedPublicNamespace GetImportCallback(String relativeUri);
+
+/**
+ * Type of the callback used by the prelinker to obtain unlinked summaries of
+ * part files of the library to be prelinked.  [relaviteUri] should be
+ * interpreted relative to the defining compilation unit of the library being
+ * prelinked.
+ *
+ * If no file exists at the given uri, `null` should be returned.
+ */
+typedef UnlinkedUnit GetPartCallback(String relativeUri);
+
+/**
+ * A [_Meaning] stores all the information necessary to find the declaration
+ * referred to by a name in a namespace.
+ */
+class _Meaning {
+  /**
+   * Which unit in the dependent library contains the declared entity.
+   */
+  final int unit;
+
+  /**
+   * The kind of entity being referred to.
+   */
+  final PrelinkedReferenceKind kind;
+
+  /**
+   * Which of the dependencies of the library being prelinked contains the
+   * declared entity.
+   */
+  final int dependency;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  final int numTypeParameters;
+
+  _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters);
+
+  /**
+   * Encode this [_Meaning] as a [PrelinkedReference].
+   */
+  PrelinkedReferenceBuilder encode() {
+    return encodePrelinkedReference(
+        unit: unit,
+        kind: kind,
+        dependency: dependency,
+        numTypeParameters: numTypeParameters);
+  }
+}
+
+/**
+ * A [_Meaning] representing a prefix introduced by an import directive.
+ */
+class _PrefixMeaning extends _Meaning {
+  final Map<String, _Meaning> namespace = <String, _Meaning>{};
+
+  _PrefixMeaning() : super(0, PrelinkedReferenceKind.prefix, 0, 0);
+}
+
+/**
+ * Helper class containing temporary data structures needed to prelink a single
+ * library.
+ *
+ * Note: throughout this class, a `null` value for a relative URI represents
+ * the defining compilation unit of the library being prelinked.
+ */
+class _Prelinker {
+  final UnlinkedUnit definingUnit;
+  final GetPartCallback getPart;
+  final GetImportCallback getImport;
+
+  /**
+   * Cache of values returned by [getImport].
+   */
+  final Map<String, UnlinkedPublicNamespace> importCache =
+      <String, UnlinkedPublicNamespace>{};
+
+  /**
+   * Cache of values returned by [getPart].
+   */
+  final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{};
+
+  /**
+   * Names defined inside the library being prelinked.
+   */
+  final Map<String, _Meaning> privateNamespace = <String, _Meaning>{
+    '': new _Meaning(0, PrelinkedReferenceKind.classOrEnum, 0, 0)
+  };
+
+  /**
+   * List of dependencies of the library being prelinked.  This will be output
+   * to [PrelinkedLibrary.dependencies].
+   */
+  final List<PrelinkedDependencyBuilder> dependencies =
+      <PrelinkedDependencyBuilder>[encodePrelinkedDependency()];
+
+  /**
+   * Map from the relative URI of a dependent library to the index of the
+   * corresponding entry in [dependencies].
+   */
+  final Map<String, int> uriToDependency = <String, int>{null: 0};
+
+  /**
+   * List of public namespaces corresponding to each entry in [dependencies].
+   */
+  final List<Map<String, _Meaning>> dependencyToPublicNamespace =
+      <Map<String, _Meaning>>[null];
+
+  _Prelinker(this.definingUnit, this.getPart, this.getImport) {
+    partCache[null] = definingUnit;
+    importCache[null] = definingUnit.publicNamespace;
+  }
+
+  /**
+   * Compute the public namespace for the library whose URI is reachable from
+   * [definingUnit] via [relativeUri], by aggregating together public namespace
+   * information from all of its parts.
+   */
+  Map<String, _Meaning> aggregatePublicNamespace(String relativeUri) {
+    if (uriToDependency.containsKey(relativeUri)) {
+      return dependencyToPublicNamespace[uriToDependency[relativeUri]];
+    }
+    assert(dependencies.length == dependencyToPublicNamespace.length);
+    int dependency = dependencies.length;
+    uriToDependency[relativeUri] = dependency;
+    List<String> unitUris = getUnitUris(relativeUri);
+    PrelinkedDependencyBuilder prelinkedDependency =
+        encodePrelinkedDependency(uri: relativeUri, parts: unitUris.sublist(1));
+    dependencies.add(prelinkedDependency);
+
+    Map<String, _Meaning> aggregated = <String, _Meaning>{};
+
+    for (int unitNum = 0; unitNum < unitUris.length; unitNum++) {
+      String unitUri = unitUris[unitNum];
+      UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri);
+      if (importedNamespace == null) {
+        continue;
+      }
+      for (UnlinkedPublicName name in importedNamespace.names) {
+        aggregated.putIfAbsent(
+            name.name,
+            () => new _Meaning(
+                unitNum, name.kind, dependency, name.numTypeParameters));
+      }
+    }
+
+    dependencyToPublicNamespace.add(aggregated);
+    return aggregated;
+  }
+
+  /**
+   * Compute the export namespace for the library whose URI is reachable from
+   * [definingUnit] via [relativeUri], by aggregating together public namespace
+   * information from the library and the transitive closure of its exports.
+   */
+  Map<String, _Meaning> computeExportNamespace(String relativeUri) {
+    Map<String, _Meaning> exportNamespace =
+        aggregatePublicNamespace(relativeUri);
+    void chaseExports(
+        NameFilter filter, String relativeUri, Set<String> seenUris) {
+      if (seenUris.add(relativeUri)) {
+        UnlinkedPublicNamespace exportedNamespace =
+            getImportCached(relativeUri);
+        if (exportedNamespace != null) {
+          for (UnlinkedExportPublic export in exportedNamespace.exports) {
+            String exportUri = resolveUri(relativeUri, export.uri);
+            aggregatePublicNamespace(exportUri)
+                .forEach((String name, _Meaning meaning) {
+              if (filter.accepts(name) && !exportNamespace.containsKey(name)) {
+                exportNamespace[name] = meaning;
+              }
+            });
+            chaseExports(
+                filter.merge(
+                    new NameFilter.forUnlinkedCombinators(export.combinators)),
+                exportUri,
+                seenUris);
+          }
+        }
+        seenUris.remove(relativeUri);
+      }
+    }
+    chaseExports(NameFilter.identity, relativeUri, new Set<String>());
+    return exportNamespace;
+  }
+
+  /**
+   * Extract all the names defined in [unit] (which is the [unitNum]th unit in
+   * the library being prelinked) and store them in [privateNamespace].
+   * Excludes names introduced by `import` statements.
+   */
+  void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
+    for (UnlinkedClass cls in unit.classes) {
+      privateNamespace.putIfAbsent(
+          cls.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0,
+              cls.typeParameters.length));
+    }
+    for (UnlinkedEnum enm in unit.enums) {
+      privateNamespace.putIfAbsent(
+          enm.name,
+          () =>
+              new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0, 0));
+    }
+    for (UnlinkedExecutable executable in unit.executables) {
+      privateNamespace.putIfAbsent(
+          executable.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0,
+              executable.typeParameters.length));
+    }
+    for (UnlinkedTypedef typedef in unit.typedefs) {
+      privateNamespace.putIfAbsent(
+          typedef.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.typedef, 0,
+              typedef.typeParameters.length));
+    }
+    for (UnlinkedVariable variable in unit.variables) {
+      privateNamespace.putIfAbsent(variable.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0, 0));
+    }
+  }
+
+  /**
+   * Filter the export namespace for the library whose URI is reachable from
+   * [definingUnit] via [relativeUri], retaining only those names accepted by
+   * [combinators], and store the resulting names in [result].  Names that
+   * already exist in [result] are not overwritten.
+   */
+  void filterExportNamespace(String relativeUri,
+      List<UnlinkedCombinator> combinators, Map<String, _Meaning> result) {
+    Map<String, _Meaning> exportNamespace = computeExportNamespace(relativeUri);
+    NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators);
+    exportNamespace.forEach((String name, _Meaning meaning) {
+      if (filter.accepts(name) && !result.containsKey(name)) {
+        result[name] = meaning;
+      }
+    });
+  }
+
+  /**
+   * Wrapper around [getImport] that caches the return value in [importCache].
+   */
+  UnlinkedPublicNamespace getImportCached(String relativeUri) {
+    return importCache.putIfAbsent(relativeUri, () => getImport(relativeUri));
+  }
+
+  /**
+   * Wrapper around [getPart] that caches the return value in [partCache] and
+   * updates [importCache] appropriately.
+   */
+  UnlinkedUnit getPartCached(String relativeUri) {
+    return partCache.putIfAbsent(relativeUri, () {
+      UnlinkedUnit unit = getPart(relativeUri);
+      importCache[relativeUri] = unit?.publicNamespace;
+      return unit;
+    });
+  }
+
+  /**
+   * Compute the set of relative URIs of all the compilation units in the
+   * library whose URI is reachable from [definingUnit] via [relativeUri].
+   */
+  List<String> getUnitUris(String relativeUri) {
+    List<String> result = <String>[relativeUri];
+    UnlinkedPublicNamespace publicNamespace = getImportCached(relativeUri);
+    if (publicNamespace != null) {
+      result.addAll(publicNamespace.parts
+          .map((String uri) => resolveUri(relativeUri, uri)));
+    }
+    return result;
+  }
+
+  /**
+   * Process a single `import` declaration in the library being prelinked.  The
+   * return value is the index of the imported library in [dependencies].
+   */
+  int handleImport(UnlinkedImport import) {
+    String uri = import.isImplicit ? 'dart:core' : import.uri;
+    Map<String, _Meaning> targetNamespace = null;
+    if (import.prefixReference != 0) {
+      // The name introduced by an import declaration can't have a prefix of
+      // its own.
+      assert(
+          definingUnit.references[import.prefixReference].prefixReference == 0);
+      String prefix = definingUnit.references[import.prefixReference].name;
+      _Meaning prefixMeaning = privateNamespace[prefix];
+      if (prefixMeaning is _PrefixMeaning) {
+        targetNamespace = prefixMeaning.namespace;
+      }
+    } else {
+      targetNamespace = privateNamespace;
+    }
+    filterExportNamespace(uri, import.combinators, targetNamespace);
+    return uriToDependency[uri];
+  }
+
+  /**
+   * Produce a [PrelinkedUnit] for the given [unit], by resolving every one of
+   * its references.
+   */
+  PrelinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
+    if (unit == null) {
+      return encodePrelinkedUnit();
+    }
+    Map<int, Map<String, _Meaning>> prefixNamespaces =
+        <int, Map<String, _Meaning>>{};
+    List<PrelinkedReferenceBuilder> references = <PrelinkedReferenceBuilder>[];
+    for (int i = 0; i < unit.references.length; i++) {
+      UnlinkedReference reference = unit.references[i];
+      Map<String, _Meaning> namespace;
+      if (reference.prefixReference != 0) {
+        // Prefix references must always point backward.
+        assert(reference.prefixReference < i);
+        namespace = prefixNamespaces[reference.prefixReference];
+        // Prefix references must always point to proper prefixes.
+        assert(namespace != null);
+      } else {
+        namespace = privateNamespace;
+      }
+      _Meaning meaning = namespace[reference.name];
+      if (meaning != null) {
+        if (meaning is _PrefixMeaning) {
+          prefixNamespaces[i] = meaning.namespace;
+        }
+        references.add(meaning.encode());
+      } else {
+        references.add(
+            encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved));
+      }
+    }
+    return encodePrelinkedUnit(references: references);
+  }
+
+  /**
+   * Form the [PrelinkedLibrary] for the [definingUnit] that was passed to the
+   * constructor.
+   */
+  PrelinkedLibraryBuilder prelink() {
+    // Gather up the unlinked summaries for all the compilation units in the
+    // library.
+    List<UnlinkedUnit> units = getUnitUris(null).map(getPartCached).toList();
+
+    // Create the private namespace for the library by gathering all the names
+    // defined in its compilation units.
+    for (int unitNum = 0; unitNum < units.length; unitNum++) {
+      UnlinkedUnit unit = units[unitNum];
+      if (unit != null) {
+        extractPrivateNames(unit, unitNum);
+      }
+    }
+
+    // Fill in prefixes defined in import declarations.
+    for (UnlinkedImport import in units[0].imports) {
+      if (import.prefixReference != 0) {
+        privateNamespace.putIfAbsent(
+            units[0].references[import.prefixReference].name,
+            () => new _PrefixMeaning());
+      }
+    }
+
+    // Fill in imported names.
+    List<int> importDependencies =
+        definingUnit.imports.map(handleImport).toList();
+
+    // Link each compilation unit.
+    List<PrelinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
+
+    return encodePrelinkedLibrary(
+        units: linkedUnits,
+        dependencies: dependencies,
+        importDependencies: importDependencies);
+  }
+
+  /**
+   * Resolve [relativeUri] relative to [sourceUri].  Works correctly if
+   * [sourceUri] is also relative.
+   */
+  String resolveUri(String sourceUri, String relativeUri) {
+    if (sourceUri == null) {
+      return relativeUri;
+    } else {
+      return Uri.parse(sourceUri).resolve(relativeUri).toString();
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index bd9e3a2..e8751b0 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -5,51 +5,49 @@
 library analyzer.src.summary.public_namespace_visitor;
 
 import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/summary/base.dart';
 import 'package:analyzer/src/summary/format.dart';
 
 /**
  * Compute the public namespace portion of the summary for the given [unit],
  * which is presumed to be an unresolved AST.
  */
-UnlinkedPublicNamespaceBuilder computePublicNamespace(
-    BuilderContext ctx, CompilationUnit unit) {
-  _PublicNamespaceVisitor visitor = new _PublicNamespaceVisitor(ctx);
+UnlinkedPublicNamespaceBuilder computePublicNamespace(CompilationUnit unit) {
+  _PublicNamespaceVisitor visitor = new _PublicNamespaceVisitor();
   unit.accept(visitor);
-  return encodeUnlinkedPublicNamespace(ctx,
+  return encodeUnlinkedPublicNamespace(
       names: visitor.names, exports: visitor.exports, parts: visitor.parts);
 }
 
 class _CombinatorEncoder extends SimpleAstVisitor<UnlinkedCombinatorBuilder> {
-  final BuilderContext ctx;
-
-  _CombinatorEncoder(this.ctx);
+  _CombinatorEncoder();
 
   List<String> encodeNames(NodeList<SimpleIdentifier> names) =>
       names.map((SimpleIdentifier id) => id.name).toList();
 
   @override
   UnlinkedCombinatorBuilder visitHideCombinator(HideCombinator node) {
-    return encodeUnlinkedCombinator(ctx, hides: encodeNames(node.hiddenNames));
+    return encodeUnlinkedCombinator(hides: encodeNames(node.hiddenNames));
   }
 
   @override
   UnlinkedCombinatorBuilder visitShowCombinator(ShowCombinator node) {
-    return encodeUnlinkedCombinator(ctx, shows: encodeNames(node.shownNames));
+    return encodeUnlinkedCombinator(shows: encodeNames(node.shownNames));
   }
 }
 
 class _PublicNamespaceVisitor extends RecursiveAstVisitor {
-  final BuilderContext ctx;
   final List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
-  final List<UnlinkedExportBuilder> exports = <UnlinkedExportBuilder>[];
-  final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
+  final List<UnlinkedExportPublicBuilder> exports =
+      <UnlinkedExportPublicBuilder>[];
+  final List<String> parts = <String>[];
 
-  _PublicNamespaceVisitor(this.ctx);
+  _PublicNamespaceVisitor();
 
-  void addNameIfPublic(String name, PrelinkedReferenceKind kind) {
+  void addNameIfPublic(
+      String name, PrelinkedReferenceKind kind, int numTypeParameters) {
     if (isPublic(name)) {
-      names.add(encodeUnlinkedPublicName(ctx, name: name, kind: kind));
+      names.add(encodeUnlinkedPublicName(
+          name: name, kind: kind, numTypeParameters: numTypeParameters));
     }
   }
 
@@ -57,25 +55,27 @@
 
   @override
   visitClassDeclaration(ClassDeclaration node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum);
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum,
+        node.typeParameters?.typeParameters?.length ?? 0);
   }
 
   @override
   visitClassTypeAlias(ClassTypeAlias node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum);
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum,
+        node.typeParameters?.typeParameters?.length ?? 0);
   }
 
   @override
   visitEnumDeclaration(EnumDeclaration node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum);
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum, 0);
   }
 
   @override
   visitExportDirective(ExportDirective node) {
-    exports.add(encodeUnlinkedExport(ctx,
+    exports.add(encodeUnlinkedExportPublic(
         uri: node.uri.stringValue,
         combinators: node.combinators
-            .map((Combinator c) => c.accept(new _CombinatorEncoder(ctx)))
+            .map((Combinator c) => c.accept(new _CombinatorEncoder()))
             .toList()));
   }
 
@@ -85,25 +85,27 @@
     if (node.isSetter) {
       name += '=';
     }
-    addNameIfPublic(name, PrelinkedReferenceKind.other);
+    addNameIfPublic(name, PrelinkedReferenceKind.other,
+        node.functionExpression.typeParameters?.typeParameters?.length ?? 0);
   }
 
   @override
   visitFunctionTypeAlias(FunctionTypeAlias node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.typedef);
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.typedef,
+        node.typeParameters?.typeParameters?.length ?? 0);
   }
 
   @override
   visitPartDirective(PartDirective node) {
-    parts.add(encodeUnlinkedPart(ctx, uri: node.uri.stringValue));
+    parts.add(node.uri.stringValue);
   }
 
   @override
   visitVariableDeclaration(VariableDeclaration node) {
     String name = node.name.name;
-    addNameIfPublic(name, PrelinkedReferenceKind.other);
+    addNameIfPublic(name, PrelinkedReferenceKind.other, 0);
     if (!node.isFinal && !node.isConst) {
-      addNameIfPublic('$name=', PrelinkedReferenceKind.other);
+      addNameIfPublic('$name=', PrelinkedReferenceKind.other, 0);
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index e83b661..23b103c 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -117,9 +117,9 @@
         getUnlinkedSummary(uri)
       ];
       Source librarySource = _getSource(uri);
-      for (UnlinkedPart part in serializedUnits[0].publicNamespace.parts) {
-        String partAbsUri =
-            sourceFactory.resolveUri(librarySource, part.uri).uri.toString();
+      for (String part in serializedUnits[0].publicNamespace.parts) {
+        Source partSource = sourceFactory.resolveUri(librarySource, part);
+        String partAbsUri = partSource.uri.toString();
         serializedUnits.add(getUnlinkedSummary(partAbsUri));
       }
       _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
@@ -200,11 +200,15 @@
       <String, Map<String, Element>>{};
 
   /**
-   * Type parameters for the class or typedef currently being resynthesized.
-   *
-   * TODO(paulberry): extend this to do the right thing for generic methods.
+   * Type parameters for the generic class, typedef, or executable currently
+   * being resynthesized, if any.  If multiple entities with type parameters
+   * are nested (e.g. a generic executable inside a generic class), this is the
+   * concatenation of all type parameters from all declarations currently in
+   * force, with the outermost declaration appearing first.  If there are no
+   * type parameters, or we are not currently resynthesizing a class, typedef,
+   * or executable, then this is an empty list.
    */
-  List<TypeParameterElement> currentTypeParameters;
+  List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[];
 
   _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary,
       this.unlinkedUnits, this.librarySource) {
@@ -212,6 +216,13 @@
   }
 
   /**
+   * Return a list of type arguments corresponding to [currentTypeParameters].
+   */
+  List<TypeParameterType> get currentTypeArguments => currentTypeParameters
+      ?.map((TypeParameterElement param) => param.type)
+      ?.toList();
+
+  /**
    * Resynthesize a [ClassElement] and place it in [unitHolder].
    */
   void buildClass(UnlinkedClass serializedClass) {
@@ -222,8 +233,8 @@
         finishTypeParameter(
             serializedClass.typeParameters[i], currentTypeParameters[i]);
       }
-      ClassElementImpl classElement =
-          new ClassElementImpl(serializedClass.name, -1);
+      ClassElementImpl classElement = new ClassElementImpl(
+          serializedClass.name, serializedClass.nameOffset);
       classElement.mixinApplication = serializedClass.isMixinApplication;
       InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
       if (serializedClass.supertype != null) {
@@ -246,7 +257,8 @@
         switch (serializedExecutable.kind) {
           case UnlinkedExecutableKind.constructor:
             constructorFound = true;
-            buildConstructor(serializedExecutable, memberHolder);
+            buildConstructor(
+                serializedExecutable, memberHolder, correspondingType);
             break;
           case UnlinkedExecutableKind.functionOrMethod:
           case UnlinkedExecutableKind.getter:
@@ -266,11 +278,7 @@
           constructor.synthetic = true;
           constructor.returnType = correspondingType;
           constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
-              constructor,
-              null,
-              currentTypeParameters
-                  .map((TypeParameterElement e) => e.type)
-                  .toList());
+              constructor, null, currentTypeArguments, false);
           memberHolder.addConstructor(constructor);
         }
         classElement.constructors = memberHolder.constructors;
@@ -278,12 +286,12 @@
       classElement.accessors = memberHolder.accessors;
       classElement.fields = memberHolder.fields;
       classElement.methods = memberHolder.methods;
-      correspondingType.typeArguments =
-          currentTypeParameters.map((param) => param.type).toList();
+      correspondingType.typeArguments = currentTypeArguments;
       classElement.type = correspondingType;
+      buildDocumentation(classElement, serializedClass.documentationComment);
       unitHolder.addType(classElement);
     } finally {
-      currentTypeParameters = null;
+      currentTypeParameters = <TypeParameterElement>[];
     }
   }
 
@@ -308,12 +316,15 @@
 
   /**
    * Resynthesize a [ConstructorElement] and place it in the given [holder].
+   * [classType] is the type of the class for which this element is a
+   * constructor.
    */
-  void buildConstructor(
-      UnlinkedExecutable serializedExecutable, ElementHolder holder) {
+  void buildConstructor(UnlinkedExecutable serializedExecutable,
+      ElementHolder holder, InterfaceType classType) {
     assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor);
-    ConstructorElementImpl constructorElement =
-        new ConstructorElementImpl(serializedExecutable.name, -1);
+    ConstructorElementImpl constructorElement = new ConstructorElementImpl(
+        serializedExecutable.name, serializedExecutable.nameOffset);
+    constructorElement.returnType = classType;
     buildExecutableCommonParts(constructorElement, serializedExecutable);
     constructorElement.factory = serializedExecutable.isFactory;
     constructorElement.const2 = serializedExecutable.isConst;
@@ -321,6 +332,19 @@
   }
 
   /**
+   * Build the documentation for the given [element].  Does nothing if
+   * [serializedDocumentationComment] is `null`.
+   */
+  void buildDocumentation(ElementImpl element,
+      UnlinkedDocumentationComment serializedDocumentationComment) {
+    if (serializedDocumentationComment != null) {
+      element.documentationComment = serializedDocumentationComment.text;
+      element.setDocRange(serializedDocumentationComment.offset,
+          serializedDocumentationComment.length);
+    }
+  }
+
+  /**
    * Resynthesize the [ClassElement] corresponding to an enum, along with the
    * associated fields and implicit accessors.
    */
@@ -328,11 +352,12 @@
     assert(!isCoreLibrary);
     // TODO(paulberry): add offset support (for this element type and others)
     ClassElementImpl classElement =
-        new ClassElementImpl(serializedEnum.name, -1);
+        new ClassElementImpl(serializedEnum.name, serializedEnum.nameOffset);
     classElement.enum2 = true;
     InterfaceType enumType = new InterfaceTypeImpl(classElement);
     classElement.type = enumType;
     classElement.supertype = summaryResynthesizer.typeProvider.objectType;
+    buildDocumentation(classElement, serializedEnum.documentationComment);
     ElementHolder memberHolder = new ElementHolder();
     FieldElementImpl indexField = new FieldElementImpl('index', -1);
     indexField.final2 = true;
@@ -349,8 +374,8 @@
     memberHolder.addField(valuesField);
     buildImplicitAccessors(valuesField, memberHolder);
     for (UnlinkedEnumValue serializedEnumValue in serializedEnum.values) {
-      ConstFieldElementImpl valueField =
-          new ConstFieldElementImpl(serializedEnumValue.name, -1);
+      ConstFieldElementImpl valueField = new ConstFieldElementImpl(
+          serializedEnumValue.name, serializedEnumValue.nameOffset);
       valueField.const3 = true;
       valueField.static = true;
       valueField.type = enumType;
@@ -382,11 +407,12 @@
       case UnlinkedExecutableKind.functionOrMethod:
         if (isTopLevel) {
           FunctionElementImpl executableElement =
-              new FunctionElementImpl(name, -1);
+              new FunctionElementImpl(name, serializedExecutable.nameOffset);
           buildExecutableCommonParts(executableElement, serializedExecutable);
           holder.addFunction(executableElement);
         } else {
-          MethodElementImpl executableElement = new MethodElementImpl(name, -1);
+          MethodElementImpl executableElement =
+              new MethodElementImpl(name, serializedExecutable.nameOffset);
           buildExecutableCommonParts(executableElement, serializedExecutable);
           executableElement.static = serializedExecutable.isStatic;
           holder.addMethod(executableElement);
@@ -395,7 +421,8 @@
       case UnlinkedExecutableKind.getter:
       case UnlinkedExecutableKind.setter:
         PropertyAccessorElementImpl executableElement =
-            new PropertyAccessorElementImpl(name, -1);
+            new PropertyAccessorElementImpl(
+                name, serializedExecutable.nameOffset);
         if (isTopLevel) {
           executableElement.static = true;
         } else {
@@ -445,39 +472,53 @@
    */
   void buildExecutableCommonParts(ExecutableElementImpl executableElement,
       UnlinkedExecutable serializedExecutable) {
+    List<TypeParameterType> oldTypeArguments = currentTypeArguments;
+    int oldTypeParametersLength = currentTypeParameters.length;
+    if (serializedExecutable.typeParameters.isNotEmpty) {
+      executableElement.typeParameters =
+          serializedExecutable.typeParameters.map(buildTypeParameter).toList();
+      currentTypeParameters.addAll(executableElement.typeParameters);
+    }
     executableElement.parameters =
         serializedExecutable.parameters.map(buildParameter).toList();
     if (serializedExecutable.returnType != null) {
       executableElement.returnType = buildType(serializedExecutable.returnType);
+    } else if (serializedExecutable.kind ==
+        UnlinkedExecutableKind.constructor) {
+      // Return type was set by the caller.
     } else {
       executableElement.returnType = VoidTypeImpl.instance;
     }
     executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
-        executableElement,
-        null,
-        currentTypeParameters
-            ?.map((TypeParameterElement e) => e.type)
-            ?.toList());
+        executableElement, null, oldTypeArguments, false);
     executableElement.hasImplicitReturnType =
         serializedExecutable.hasImplicitReturnType;
     executableElement.external = serializedExecutable.isExternal;
+    currentTypeParameters.removeRange(
+        oldTypeParametersLength, currentTypeParameters.length);
+    buildDocumentation(
+        executableElement, serializedExecutable.documentationComment);
   }
 
   /**
    * Resynthesize an [ExportElement],
    */
-  ExportElement buildExport(UnlinkedExport serializedExport) {
-    ExportElementImpl exportElement = new ExportElementImpl(0);
+  ExportElement buildExport(UnlinkedExportPublic serializedExportPublic,
+      UnlinkedExportNonPublic serializedExportNonPublic) {
+    ExportElementImpl exportElement =
+        new ExportElementImpl(serializedExportNonPublic.offset);
     String exportedLibraryUri = summaryResynthesizer.sourceFactory
-        .resolveUri(librarySource, serializedExport.uri)
+        .resolveUri(librarySource, serializedExportPublic.uri)
         .uri
         .toString();
     exportElement.exportedLibrary = new LibraryElementHandle(
         summaryResynthesizer,
         new ElementLocationImpl.con3(<String>[exportedLibraryUri]));
-    exportElement.uri = serializedExport.uri;
+    exportElement.uri = serializedExportPublic.uri;
     exportElement.combinators =
-        serializedExport.combinators.map(buildCombinator).toList();
+        serializedExportPublic.combinators.map(buildCombinator).toList();
+    exportElement.uriOffset = serializedExportNonPublic.uriOffset;
+    exportElement.uriEnd = serializedExportNonPublic.uriEnd;
     return exportElement;
   }
 
@@ -501,23 +542,24 @@
     String name = element.name;
     DartType type = element.type;
     PropertyAccessorElementImpl getter =
-        new PropertyAccessorElementImpl(name, -1);
+        new PropertyAccessorElementImpl(name, element.nameOffset);
     getter.getter = true;
     getter.static = element.isStatic;
     getter.synthetic = true;
     getter.returnType = type;
     getter.type = new FunctionTypeImpl(getter);
     getter.variable = element;
+    getter.hasImplicitReturnType = element.hasImplicitType;
     holder.addAccessor(getter);
     element.getter = getter;
     if (!(element.isConst || element.isFinal)) {
       PropertyAccessorElementImpl setter =
-          new PropertyAccessorElementImpl(name, -1);
+          new PropertyAccessorElementImpl(name, element.nameOffset);
       setter.setter = true;
       setter.static = element.isStatic;
       setter.synthetic = true;
       setter.parameters = <ParameterElement>[
-        new ParameterElementImpl('_$name', -1)
+        new ParameterElementImpl('_$name', element.nameOffset)
           ..synthetic = true
           ..type = type
           ..parameterKind = ParameterKind.REQUIRED
@@ -557,18 +599,17 @@
    */
   PropertyInducingElementImpl buildImplicitTopLevelVariable(
       String name, UnlinkedExecutableKind kind, ElementHolder holder) {
-    if (holder.getTopLevelVariable(name) == null) {
-      TopLevelVariableElementImpl variable =
-          new TopLevelVariableElementImpl(name, -1);
+    TopLevelVariableElementImpl variable = holder.getTopLevelVariable(name);
+    if (variable == null) {
+      variable = new TopLevelVariableElementImpl(name, -1);
       variable.synthetic = true;
       variable.final2 = kind == UnlinkedExecutableKind.getter;
       holder.addTopLevelVariable(variable);
       return variable;
     } else {
-      // TODO(paulberry): if adding a setter where there was previously
-      // only a getter, remove "final" modifier.
       // TODO(paulberry): what if the getter and setter have a type mismatch?
-      throw new UnimplementedError();
+      variable.final2 = false;
+      return variable;
     }
   }
 
@@ -593,11 +634,14 @@
       importElement.synthetic = true;
     } else {
       importElement.uri = serializedImport.uri;
+      importElement.uriOffset = serializedImport.uriOffset;
+      importElement.uriEnd = serializedImport.uriEnd;
     }
     if (serializedImport.prefixReference != 0) {
       UnlinkedReference serializedPrefix =
           unlinkedUnits[0].references[serializedImport.prefixReference];
-      importElement.prefix = new PrefixElementImpl(serializedPrefix.name, -1);
+      importElement.prefix = new PrefixElementImpl(
+          serializedPrefix.name, serializedImport.prefixOffset);
     }
     importElement.combinators =
         serializedImport.combinators.map(buildCombinator).toList();
@@ -608,9 +652,14 @@
    * Main entry point.  Resynthesize the [LibraryElement] and return it.
    */
   LibraryElement buildLibrary() {
-    // TODO(paulberry): is it ok to pass -1 for offset and nameLength?
+    bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
     LibraryElementImpl libraryElement = new LibraryElementImpl(
-        summaryResynthesizer.context, unlinkedUnits[0].libraryName, -1, -1);
+        summaryResynthesizer.context,
+        unlinkedUnits[0].libraryName,
+        hasName ? unlinkedUnits[0].libraryNameOffset : -1,
+        unlinkedUnits[0].libraryNameLength);
+    buildDocumentation(
+        libraryElement, unlinkedUnits[0].libraryDocumentationComment);
     CompilationUnitElementImpl definingCompilationUnit =
         new CompilationUnitElementImpl(librarySource.shortName);
     libraryElement.definingCompilationUnit = definingCompilationUnit;
@@ -622,7 +671,8 @@
         prelinkedLibrary.units.length);
     for (int i = 1; i < prelinkedLibrary.units.length; i++) {
       CompilationUnitElementImpl part = buildPart(
-          unlinkedDefiningUnit.publicNamespace.parts[i - 1].uri,
+          unlinkedDefiningUnit.publicNamespace.parts[i - 1],
+          unlinkedDefiningUnit.parts[i - 1],
           unlinkedUnits[i]);
       parts.add(part);
     }
@@ -633,8 +683,14 @@
           prelinkedLibrary.importDependencies[i]));
     }
     libraryElement.imports = imports;
-    libraryElement.exports =
-        unlinkedDefiningUnit.publicNamespace.exports.map(buildExport).toList();
+    List<ExportElement> exports = <ExportElement>[];
+    assert(unlinkedDefiningUnit.exports.length ==
+        unlinkedDefiningUnit.publicNamespace.exports.length);
+    for (int i = 0; i < unlinkedDefiningUnit.exports.length; i++) {
+      exports.add(buildExport(unlinkedDefiningUnit.publicNamespace.exports[i],
+          unlinkedDefiningUnit.exports[i]));
+    }
+    libraryElement.exports = exports;
     populateUnit(definingCompilationUnit, 0);
     for (int i = 0; i < parts.length; i++) {
       populateUnit(parts[i], i + 1);
@@ -646,6 +702,19 @@
         classElement.supertype = objectElement.type;
       }
     }
+    // Compute namespaces.
+    libraryElement.publicNamespace =
+        new NamespaceBuilder().createPublicNamespaceForLibrary(libraryElement);
+    // TODO(paulberry): compute the export namespace from prelinked data, so
+    // that exported libraries won't be unnecessarily resynthesized.
+    libraryElement.exportNamespace =
+        new NamespaceBuilder().createExportNamespaceForLibrary(libraryElement);
+    // Find the entry point.
+    libraryElement.entryPoint =
+        libraryElement.exportNamespace.definedNames.values.firstWhere(
+            (element) => element is FunctionElement && element.isEntryPoint,
+            orElse: () => null);
+    // Done.
     return libraryElement;
   }
 
@@ -653,8 +722,8 @@
    * Resynthesize a [ParameterElement].
    */
   ParameterElement buildParameter(UnlinkedParam serializedParameter) {
-    ParameterElementImpl parameterElement =
-        new ParameterElementImpl(serializedParameter.name, -1);
+    ParameterElementImpl parameterElement = new ParameterElementImpl(
+        serializedParameter.name, serializedParameter.nameOffset);
     if (serializedParameter.isFunctionTyped) {
       FunctionElementImpl parameterTypeElement =
           new FunctionElementImpl('', -1);
@@ -668,7 +737,8 @@
       } else {
         parameterTypeElement.returnType = VoidTypeImpl.instance;
       }
-      parameterElement.type = new FunctionTypeImpl(parameterTypeElement);
+      parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
+          parameterTypeElement, null, currentTypeArguments, false);
     } else {
       parameterElement.type = buildType(serializedParameter.type);
       parameterElement.hasImplicitType = serializedParameter.hasImplicitType;
@@ -692,11 +762,13 @@
    * than the defining compilation unit.
    */
   CompilationUnitElementImpl buildPart(
-      String uri, UnlinkedUnit serializedPart) {
+      String uri, UnlinkedPart partDecl, UnlinkedUnit serializedPart) {
     Source unitSource =
         summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
     CompilationUnitElementImpl partUnit =
         new CompilationUnitElementImpl(unitSource.shortName);
+    partUnit.uriOffset = partDecl.uriOffset;
+    partUnit.uriEnd = partDecl.uriEnd;
     partUnit.source = unitSource;
     partUnit.librarySource = librarySource;
     partUnit.uri = uri;
@@ -713,7 +785,8 @@
     if (type.paramReference != 0) {
       // TODO(paulberry): make this work for generic methods.
       return currentTypeParameters[
-          currentTypeParameters.length - type.paramReference].type;
+              currentTypeParameters.length - type.paramReference]
+          .type;
     } else {
       // TODO(paulberry): handle references to things other than classes (note:
       // this should only occur in the case of erroneous code).
@@ -738,7 +811,7 @@
           UnlinkedUnit referencedLibraryDefiningUnit =
               summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri);
           String uri = referencedLibraryDefiningUnit.publicNamespace.parts[
-              referenceResolution.unit - 1].uri;
+              referenceResolution.unit - 1];
           Source partSource = summaryResynthesizer.sourceFactory
               .resolveUri(referencedLibrarySource, uri);
           partUri = partSource.uri.toString();
@@ -754,7 +827,7 @@
         referencedLibraryUri = librarySource.uri.toString();
         if (referenceResolution.unit != 0) {
           String uri = unlinkedUnits[0].publicNamespace.parts[
-              referenceResolution.unit - 1].uri;
+              referenceResolution.unit - 1];
           Source partSource =
               summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
           partUri = partSource.uri.toString();
@@ -786,7 +859,8 @@
               new FunctionTypeAliasElementHandle(
                   summaryResynthesizer, location),
               reference.name,
-              typeArguments);
+              typeArguments,
+              typeArguments.isNotEmpty);
         default:
           // TODO(paulberry): figure out how to handle this case (which should
           // only occur in the event of erroneous code).
@@ -808,7 +882,8 @@
             serializedTypedef.typeParameters[i], currentTypeParameters[i]);
       }
       FunctionTypeAliasElementImpl functionTypeAliasElement =
-          new FunctionTypeAliasElementImpl(serializedTypedef.name, -1);
+          new FunctionTypeAliasElementImpl(
+              serializedTypedef.name, serializedTypedef.nameOffset);
       functionTypeAliasElement.parameters =
           serializedTypedef.parameters.map(buildParameter).toList();
       if (serializedTypedef.returnType != null) {
@@ -820,9 +895,11 @@
       functionTypeAliasElement.type =
           new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
       functionTypeAliasElement.typeParameters = currentTypeParameters;
+      buildDocumentation(
+          functionTypeAliasElement, serializedTypedef.documentationComment);
       unitHolder.addTypeAlias(functionTypeAliasElement);
     } finally {
-      currentTypeParameters = null;
+      currentTypeParameters = <TypeParameterElement>[];
     }
   }
 
@@ -837,7 +914,8 @@
   TypeParameterElement buildTypeParameter(
       UnlinkedTypeParam serializedTypeParameter) {
     TypeParameterElementImpl typeParameterElement =
-        new TypeParameterElementImpl(serializedTypeParameter.name, -1);
+        new TypeParameterElementImpl(
+            serializedTypeParameter.name, serializedTypeParameter.nameOffset);
     typeParameterElement.type = new TypeParameterTypeImpl(typeParameterElement);
     return typeParameterElement;
   }
@@ -848,14 +926,14 @@
   void buildVariable(UnlinkedVariable serializedVariable,
       [ElementHolder holder]) {
     if (holder == null) {
-      TopLevelVariableElementImpl element =
-          new TopLevelVariableElementImpl(serializedVariable.name, -1);
+      TopLevelVariableElementImpl element = new TopLevelVariableElementImpl(
+          serializedVariable.name, serializedVariable.nameOffset);
       buildVariableCommonParts(element, serializedVariable);
       unitHolder.addTopLevelVariable(element);
       buildImplicitAccessors(element, unitHolder);
     } else {
-      FieldElementImpl element =
-          new FieldElementImpl(serializedVariable.name, -1);
+      FieldElementImpl element = new FieldElementImpl(
+          serializedVariable.name, serializedVariable.nameOffset);
       buildVariableCommonParts(element, serializedVariable);
       element.static = serializedVariable.isStatic;
       holder.addField(element);
@@ -870,6 +948,8 @@
       UnlinkedVariable serializedVariable) {
     element.type = buildType(serializedVariable.type);
     element.const3 = serializedVariable.isConst;
+    element.hasImplicitType = serializedVariable.hasImplicitType;
+    buildDocumentation(element, serializedVariable.documentationComment);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index eddb78c..0eac910 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -9,16 +9,16 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/base.dart';
 import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/name_filter.dart';
 
 /**
  * Serialize all the elements in [lib] to a summary using [ctx] as the context
  * for building the summary, and using [typeProvider] to find built-in types.
  */
 LibrarySerializationResult serializeLibrary(
-    BuilderContext ctx, LibraryElement lib, TypeProvider typeProvider) {
-  var serializer = new _LibrarySerializer(ctx, lib, typeProvider);
+    LibraryElement lib, TypeProvider typeProvider) {
+  var serializer = new _LibrarySerializer(lib, typeProvider);
   PrelinkedLibraryBuilder prelinked = serializer.serializeLibrary();
   return new LibrarySerializationResult(
       prelinked, serializer.unlinkedUnits, serializer.unitUris);
@@ -134,12 +134,13 @@
       new Set<LibraryElement>();
 
   /**
-   * [BuilderContext] used to serialize the output summary.
+   * Map from imported element to the prefix which may be used to refer to that
+   * element; elements for which no prefix is needed are absent from this map.
    */
-  final BuilderContext ctx;
+  final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{};
 
-  _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) {
-    dependencies.add(encodePrelinkedDependency(ctx));
+  _LibrarySerializer(this.libraryElement, this.typeProvider) {
+    dependencies.add(encodePrelinkedDependency());
     dependencyMap[libraryElement] = 0;
   }
 
@@ -155,57 +156,70 @@
    * library.
    */
   void addCompilationUnitElements(CompilationUnitElement element, int unitNum) {
-    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(ctx);
+    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
     referenceMap.clear();
-    unlinkedReferences = <UnlinkedReferenceBuilder>[
-      encodeUnlinkedReference(ctx)
-    ];
+    unlinkedReferences = <UnlinkedReferenceBuilder>[encodeUnlinkedReference()];
     prelinkedReferences = <PrelinkedReferenceBuilder>[
-      encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.classOrEnum)
+      encodePrelinkedReference(kind: PrelinkedReferenceKind.classOrEnum)
     ];
     List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
     for (PropertyAccessorElement accessor in element.accessors) {
       if (accessor.isPublic) {
-        names.add(encodeUnlinkedPublicName(ctx,
-            kind: PrelinkedReferenceKind.other, name: accessor.name));
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.other,
+            name: accessor.name,
+            numTypeParameters: accessor.typeParameters.length));
       }
     }
     for (ClassElement cls in element.types) {
       if (cls.isPublic) {
-        names.add(encodeUnlinkedPublicName(ctx,
-            kind: PrelinkedReferenceKind.classOrEnum, name: cls.name));
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.classOrEnum,
+            name: cls.name,
+            numTypeParameters: cls.typeParameters.length));
       }
     }
     for (ClassElement enm in element.enums) {
       if (enm.isPublic) {
-        names.add(encodeUnlinkedPublicName(ctx,
+        names.add(encodeUnlinkedPublicName(
             kind: PrelinkedReferenceKind.classOrEnum, name: enm.name));
       }
     }
     for (FunctionElement function in element.functions) {
       if (function.isPublic) {
-        names.add(encodeUnlinkedPublicName(ctx,
-            kind: PrelinkedReferenceKind.other, name: function.name));
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.other,
+            name: function.name,
+            numTypeParameters: function.typeParameters.length));
       }
     }
     for (FunctionTypeAliasElement typedef in element.functionTypeAliases) {
       if (typedef.isPublic) {
-        names.add(encodeUnlinkedPublicName(ctx,
-            kind: PrelinkedReferenceKind.typedef, name: typedef.name));
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.typedef,
+            name: typedef.name,
+            numTypeParameters: typedef.typeParameters.length));
       }
     }
     if (unitNum == 0) {
       if (libraryElement.name.isNotEmpty) {
         b.libraryName = libraryElement.name;
+        b.libraryNameOffset = libraryElement.nameOffset;
+        b.libraryNameLength = libraryElement.nameLength;
+        b.libraryDocumentationComment = serializeDocumentation(libraryElement);
       }
-      b.publicNamespace = encodeUnlinkedPublicNamespace(ctx,
-          exports: libraryElement.exports.map(serializeExport).toList(),
+      b.publicNamespace = encodeUnlinkedPublicNamespace(
+          exports: libraryElement.exports.map(serializeExportPublic).toList(),
           parts: libraryElement.parts
-              .map((CompilationUnitElement e) =>
-                  encodeUnlinkedPart(ctx, uri: e.uri))
+              .map((CompilationUnitElement e) => e.uri)
               .toList(),
           names: names);
+      b.exports = libraryElement.exports.map(serializeExportNonPublic).toList();
       b.imports = libraryElement.imports.map(serializeImport).toList();
+      b.parts = libraryElement.parts
+          .map((CompilationUnitElement e) =>
+              encodeUnlinkedPart(uriOffset: e.uriOffset, uriEnd: e.uriEnd))
+          .toList();
     } else {
       // TODO(paulberry): we need to figure out a way to record library, part,
       // import, and export declarations that appear in non-defining
@@ -213,7 +227,7 @@
       // language), so that if the user makes code changes that cause a
       // non-defining compilation unit to become a defining compilation unit,
       // we can create a correct summary by simply re-linking.
-      b.publicNamespace = encodeUnlinkedPublicNamespace(ctx, names: names);
+      b.publicNamespace = encodeUnlinkedPublicNamespace(names: names);
     }
     b.classes = element.types.map(serializeClass).toList();
     b.enums = element.enums.map(serializeEnum).toList();
@@ -239,8 +253,7 @@
     b.variables = variables;
     b.references = unlinkedReferences;
     unlinkedUnits.add(b);
-    prelinkedUnits
-        .add(encodePrelinkedUnit(ctx, references: prelinkedReferences));
+    prelinkedUnits.add(encodePrelinkedUnit(references: prelinkedReferences));
     unitUris.add(element.source.uri.toString());
     unlinkedReferences = null;
     prelinkedReferences = null;
@@ -261,6 +274,24 @@
   }
 
   /**
+   * Fill in [prefixMap] using information from [libraryElement.imports].
+   */
+  void computePrefixMap() {
+    for (ImportElement import in libraryElement.imports) {
+      if (import.prefix == null) {
+        continue;
+      }
+      import.importedLibrary.exportNamespace.definedNames
+          .forEach((String name, Element e) {
+        if (new NameFilter.forNamespaceCombinators(import.combinators)
+            .accepts(name)) {
+          prefixMap[e] = import.prefix;
+        }
+      });
+    }
+  }
+
+  /**
    * Compute the appropriate De Bruijn index to represent the given type
    * parameter [type].
    */
@@ -293,8 +324,9 @@
    * Serialize the given [classElement], creating an [UnlinkedClass].
    */
   UnlinkedClassBuilder serializeClass(ClassElement classElement) {
-    UnlinkedClassBuilder b = new UnlinkedClassBuilder(ctx);
+    UnlinkedClassBuilder b = new UnlinkedClassBuilder();
     b.name = classElement.name;
+    b.nameOffset = classElement.nameOffset;
     b.typeParameters =
         classElement.typeParameters.map(serializeTypeParam).toList();
     if (classElement.supertype == null) {
@@ -332,6 +364,7 @@
     b.executables = executables;
     b.isAbstract = classElement.isAbstract;
     b.isMixinApplication = classElement.isMixinApplication;
+    b.documentationComment = serializeDocumentation(classElement);
     return b;
   }
 
@@ -340,7 +373,7 @@
    */
   UnlinkedCombinatorBuilder serializeCombinator(
       NamespaceCombinator combinator) {
-    UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder(ctx);
+    UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
     if (combinator is ShowElementCombinator) {
       b.shows = combinator.shownNames;
     } else if (combinator is HideElementCombinator) {
@@ -357,13 +390,32 @@
   int serializeDependency(LibraryElement dependentLibrary) {
     return dependencyMap.putIfAbsent(dependentLibrary, () {
       int index = dependencies.length;
-      dependencies.add(encodePrelinkedDependency(ctx,
-          uri: dependentLibrary.source.uri.toString()));
+      List<String> parts = dependentLibrary.parts
+          .map((CompilationUnitElement e) => e.source.uri.toString())
+          .toList();
+      dependencies.add(encodePrelinkedDependency(
+          uri: dependentLibrary.source.uri.toString(), parts: parts));
       return index;
     });
   }
 
   /**
+   * Serialize documentation from the given [element], creating an
+   * [UnlinkedDocumentationComment].
+   *
+   * If [element] has no documentation, `null` is returned.
+   */
+  UnlinkedDocumentationCommentBuilder serializeDocumentation(Element element) {
+    if (element.documentationComment == null) {
+      return null;
+    }
+    return encodeUnlinkedDocumentationComment(
+        text: element.documentationComment,
+        offset: element.docRange.offset,
+        length: element.docRange.length);
+  }
+
+  /**
    * Return the index of the entry in the references table
    * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references])
    * representing the pseudo-type `dynamic`.
@@ -374,15 +426,20 @@
    * Serialize the given [enumElement], creating an [UnlinkedEnum].
    */
   UnlinkedEnumBuilder serializeEnum(ClassElement enumElement) {
-    UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(ctx);
+    UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
     b.name = enumElement.name;
+    b.nameOffset = enumElement.nameOffset;
     List<UnlinkedEnumValueBuilder> values = <UnlinkedEnumValueBuilder>[];
     for (FieldElement field in enumElement.fields) {
       if (field.isConst && field.type.element == enumElement) {
-        values.add(encodeUnlinkedEnumValue(ctx, name: field.name));
+        values.add(encodeUnlinkedEnumValue(
+            name: field.name,
+            nameOffset: field.nameOffset,
+            documentationComment: serializeDocumentation(field)));
       }
     }
     b.values = values;
+    b.documentationComment = serializeDocumentation(enumElement);
     return b;
   }
 
@@ -391,9 +448,11 @@
    */
   UnlinkedExecutableBuilder serializeExecutable(
       ExecutableElement executableElement) {
-    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(ctx);
+    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
     b.name = executableElement.name;
-    if (!executableElement.type.returnType.isVoid) {
+    b.nameOffset = executableElement.nameOffset;
+    if (executableElement is! ConstructorElement &&
+        !executableElement.type.returnType.isVoid) {
       b.returnType = serializeTypeRef(
           executableElement.type.returnType, executableElement);
     }
@@ -419,14 +478,28 @@
         executableElement.enclosingElement is ClassElement;
     b.hasImplicitReturnType = executableElement.hasImplicitReturnType;
     b.isExternal = executableElement.isExternal;
+    b.documentationComment = serializeDocumentation(executableElement);
     return b;
   }
 
   /**
-   * Serialize the given [exportElement] into an [UnlinkedExport].
+   * Serialize the given [exportElement] into an [UnlinkedExportNonPublic].
    */
-  UnlinkedExportBuilder serializeExport(ExportElement exportElement) {
-    UnlinkedExportBuilder b = new UnlinkedExportBuilder(ctx);
+  UnlinkedExportNonPublicBuilder serializeExportNonPublic(
+      ExportElement exportElement) {
+    UnlinkedExportNonPublicBuilder b = new UnlinkedExportNonPublicBuilder();
+    b.offset = exportElement.nameOffset;
+    b.uriOffset = exportElement.uriOffset;
+    b.uriEnd = exportElement.uriEnd;
+    return b;
+  }
+
+  /**
+   * Serialize the given [exportElement] into an [UnlinkedExportPublic].
+   */
+  UnlinkedExportPublicBuilder serializeExportPublic(
+      ExportElement exportElement) {
+    UnlinkedExportPublicBuilder b = new UnlinkedExportPublicBuilder();
     b.uri = exportElement.uri;
     b.combinators = exportElement.combinators.map(serializeCombinator).toList();
     return b;
@@ -437,17 +510,20 @@
    * Also, add pre-linked information about it to the [prelinkedImports] list.
    */
   UnlinkedImportBuilder serializeImport(ImportElement importElement) {
-    UnlinkedImportBuilder b = new UnlinkedImportBuilder(ctx);
+    UnlinkedImportBuilder b = new UnlinkedImportBuilder();
     b.isDeferred = importElement.isDeferred;
     b.offset = importElement.nameOffset;
     b.combinators = importElement.combinators.map(serializeCombinator).toList();
     if (importElement.prefix != null) {
       b.prefixReference = serializePrefix(importElement.prefix);
+      b.prefixOffset = importElement.prefix.nameOffset;
     }
     if (importElement.isSynthetic) {
       b.isImplicit = true;
     } else {
       b.uri = importElement.uri;
+      b.uriOffset = importElement.uriOffset;
+      b.uriEnd = importElement.uriEnd;
     }
     addTransitiveExportClosure(importElement.importedLibrary);
     prelinkedImports.add(serializeDependency(importElement.importedLibrary));
@@ -462,7 +538,8 @@
    * absolute URIs are stored in [unitUris].
    */
   PrelinkedLibraryBuilder serializeLibrary() {
-    PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx);
+    computePrefixMap();
+    PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder();
     addCompilationUnitElements(libraryElement.definingCompilationUnit, 0);
     for (int i = 0; i < libraryElement.parts.length; i++) {
       addCompilationUnitElements(libraryElement.parts[i], i + 1);
@@ -479,8 +556,9 @@
   UnlinkedParamBuilder serializeParam(ParameterElement parameter,
       [Element context]) {
     context ??= parameter;
-    UnlinkedParamBuilder b = new UnlinkedParamBuilder(ctx);
+    UnlinkedParamBuilder b = new UnlinkedParamBuilder();
     b.name = parameter.name;
+    b.nameOffset = parameter.nameOffset;
     switch (parameter.parameterKind) {
       case ParameterKind.REQUIRED:
         b.kind = UnlinkedParamKind.required;
@@ -516,9 +594,9 @@
     return referenceMap.putIfAbsent(element, () {
       assert(unlinkedReferences.length == prelinkedReferences.length);
       int index = unlinkedReferences.length;
-      unlinkedReferences.add(encodeUnlinkedReference(ctx, name: element.name));
-      prelinkedReferences.add(
-          encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.prefix));
+      unlinkedReferences.add(encodeUnlinkedReference(name: element.name));
+      prelinkedReferences
+          .add(encodePrelinkedReference(kind: PrelinkedReferenceKind.prefix));
       return index;
     });
   }
@@ -528,8 +606,9 @@
    */
   UnlinkedTypedefBuilder serializeTypedef(
       FunctionTypeAliasElement typedefElement) {
-    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx);
+    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
     b.name = typedefElement.name;
+    b.nameOffset = typedefElement.nameOffset;
     b.typeParameters =
         typedefElement.typeParameters.map(serializeTypeParam).toList();
     if (!typedefElement.returnType.isVoid) {
@@ -537,6 +616,7 @@
           serializeTypeRef(typedefElement.returnType, typedefElement);
     }
     b.parameters = typedefElement.parameters.map(serializeParam).toList();
+    b.documentationComment = serializeDocumentation(typedefElement);
     return b;
   }
 
@@ -545,8 +625,9 @@
    */
   UnlinkedTypeParamBuilder serializeTypeParam(
       TypeParameterElement typeParameter) {
-    UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(ctx);
+    UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder();
     b.name = typeParameter.name;
+    b.nameOffset = typeParameter.nameOffset;
     if (typeParameter.bound != null) {
       b.bound = serializeTypeRef(typeParameter.bound, typeParameter);
     }
@@ -557,7 +638,7 @@
    * Serialize the given [type] into an [UnlinkedTypeRef].
    */
   UnlinkedTypeRefBuilder serializeTypeRef(DartType type, Element context) {
-    UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder(ctx);
+    UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder();
     if (type is TypeParameterType) {
       b.paramReference = findTypeParameterIndex(type, context);
     } else {
@@ -581,11 +662,20 @@
           if (element is TypeParameterizedElement) {
             numTypeParameters = element.typeParameters.length;
           }
+          // Figure out a prefix that may be used to refer to the given type.
+          // TODO(paulberry): to avoid subtle relinking inconsistencies we
+          // should use the actual prefix from the AST (a given type may be
+          // reachable via multiple prefixes), but sadly, this information is
+          // not recorded in the element model.
+          int prefixReference = 0;
+          PrefixElement prefix = prefixMap[element];
+          if (prefix != null) {
+            prefixReference = serializePrefix(prefix);
+          }
           int index = unlinkedReferences.length;
-          // TODO(paulberry): set UnlinkedReference.prefix.
-          unlinkedReferences
-              .add(encodeUnlinkedReference(ctx, name: element.name));
-          prelinkedReferences.add(encodePrelinkedReference(ctx,
+          unlinkedReferences.add(encodeUnlinkedReference(
+              name: element.name, prefixReference: prefixReference));
+          prelinkedReferences.add(encodePrelinkedReference(
               dependency: serializeDependency(dependentLibrary),
               kind: element is FunctionTypeAliasElement
                   ? PrelinkedReferenceKind.typedef
@@ -620,13 +710,14 @@
   int serializeUnresolvedReference() {
     // TODO(paulberry): in order for relinking to work, we need to record the
     // name and prefix of the unresolved symbol.  This is not (yet) encoded in
-    // the element model.
+    // the element model.  For the moment we use a name that can't possibly
+    // ever exist.
     if (unresolvedReferenceIndex == null) {
       assert(unlinkedReferences.length == prelinkedReferences.length);
       unresolvedReferenceIndex = unlinkedReferences.length;
-      unlinkedReferences.add(encodeUnlinkedReference(ctx));
-      prelinkedReferences.add(encodePrelinkedReference(ctx,
-          kind: PrelinkedReferenceKind.unresolved));
+      unlinkedReferences.add(encodeUnlinkedReference(name: '*unresolved*'));
+      prelinkedReferences.add(
+          encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved));
     }
     return unresolvedReferenceIndex;
   }
@@ -635,13 +726,15 @@
    * Serialize the given [variable], creating an [UnlinkedVariable].
    */
   UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) {
-    UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx);
+    UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
     b.name = variable.name;
+    b.nameOffset = variable.nameOffset;
     b.type = serializeTypeRef(variable.type, variable);
     b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement;
     b.isFinal = variable.isFinal;
     b.isConst = variable.isConst;
     b.hasImplicitType = variable.hasImplicitType;
+    b.documentationComment = serializeDocumentation(variable);
     return b;
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 70b7bdd..4d9b9fe 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -79,9 +79,16 @@
         entry.setValue(result, true, TargetedResult.EMPTY_LIST);
         return true;
       } else if (result == SOURCE_KIND) {
-        // TODO(scheglov) not every source is a library
-        entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
-        return true;
+        String uri = target.uri.toString();
+        if (bundle.prelinkedLibraryUris.contains(uri)) {
+          entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        if (bundle.unlinkedUnitUris.contains(uri)) {
+          entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        return false;
       } else {
 //        throw new UnimplementedError('$result of $target');
       }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 56dc665..df4e7ac 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -3550,6 +3550,7 @@
     RecordingErrorListener errorListener = new RecordingErrorListener();
     Parser parser = new Parser(source, errorListener);
     AnalysisOptions options = context.analysisOptions;
+    parser.parseAsync = options.enableAsync;
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
     parser.parseGenericMethods = options.enableGenericMethods;
     parser.parseGenericMethodComments = options.strongMode;
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index ebc5a4c..6775408 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -39,6 +39,7 @@
 /// `analyzer` analysis options constants.
 class AnalyzerOptions {
   static const String analyzer = 'analyzer';
+  static const String enableAsync = 'enableAsync';
   static const String enableGenericMethods = 'enableGenericMethods';
   static const String enableSuperMixins = 'enableSuperMixins';
   static const String errors = 'errors';
@@ -71,6 +72,7 @@
 
   /// Supported `analyzer` language configuration options.
   static const List<String> languageOptions = const [
+    enableAsync,
     enableGenericMethods,
     enableSuperMixins
   ];
@@ -425,6 +427,14 @@
 
   void setLanguageOption(
       AnalysisContext context, Object feature, Object value) {
+    if (feature == AnalyzerOptions.enableAsync) {
+      if (isFalse(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableAsync = false;
+        context.analysisOptions = options;
+      }
+    }
     if (feature == AnalyzerOptions.enableSuperMixins) {
       if (isTrue(value)) {
         AnalysisOptionsImpl options =
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 2ad6c59..29857b0 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -189,11 +189,12 @@
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
     var token = node.operator;
-    if (token.type != TokenType.EQ) {
-      _checkCompoundAssignment(node);
-    } else {
+    if (token.type == TokenType.EQ ||
+        token.type == TokenType.QUESTION_QUESTION_EQ) {
       DartType staticType = _getStaticType(node.leftHandSide);
       checkAssignment(node.rightHandSide, staticType);
+    } else {
+      _checkCompoundAssignment(node);
     }
     node.visitChildren(this);
   }
@@ -788,8 +789,14 @@
   /// in the caller position of a call (that is, accounting
   /// for the possibility of a call method).  Returns null
   /// if expression is not statically callable.
-  FunctionType _getTypeAsCaller(Expression applicand) {
-    var t = applicand.staticType ?? DynamicTypeImpl.instance;
+  FunctionType _getTypeAsCaller(Expression node) {
+    DartType t = node.staticType;
+    if (node is SimpleIdentifier) {
+      Expression parent = node.parent;
+      if (parent is MethodInvocation) {
+        t = parent.staticInvokeType;
+      }
+    }
     if (t is InterfaceType) {
       return rules.getCallMethodType(t);
     }
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index bb6c95a..f8ca1dc 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -575,22 +575,19 @@
     expect(_findConstants(), contains(field.element));
   }
 
-  void
-      test_visitVariableDeclaration_static_const_inClassWithConstConstructor() {
+  void test_visitVariableDeclaration_static_const_inClassWithConstConstructor() {
     VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.CONST,
         isStatic: true, hasConstConstructor: true);
     expect(_findConstants(), contains(field.element));
   }
 
-  void
-      test_visitVariableDeclaration_static_final_inClassWithConstConstructor() {
+  void test_visitVariableDeclaration_static_final_inClassWithConstConstructor() {
     VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
         isStatic: true, hasConstConstructor: true);
     expect(_findConstants(), isNot(contains(field.element)));
   }
 
-  void
-      test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
+  void test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
     VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
         isInitialized: false, hasConstConstructor: true);
     expect(_findConstants(), isNot(contains(field.element)));
@@ -624,8 +621,8 @@
 
   ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
     Keyword constKeyword = isConst ? Keyword.CONST : null;
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration2(
             constKeyword,
             null,
             null,
@@ -666,8 +663,8 @@
     classElement.fields = <FieldElement>[fieldElement];
     classDeclaration.name.staticElement = classElement;
     if (hasConstConstructor) {
-      ConstructorDeclaration constructorDeclaration =
-          AstFactory.constructorDeclaration2(
+      ConstructorDeclaration constructorDeclaration = AstFactory
+          .constructorDeclaration2(
               Keyword.CONST,
               null,
               AstFactory.identifier3(className),
@@ -880,23 +877,27 @@
   void test_computeValues_cycle() {
     TestLogger logger = new TestLogger();
     AnalysisEngine.instance.logger = logger;
-    Source librarySource = addSource(r'''
-const int a = c;
-const int b = a;
-const int c = b;''');
-    LibraryElement libraryElement = resolve2(librarySource);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-    analysisContext.computeErrors(librarySource);
-    expect(unit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, librarySource, librarySource);
-    computer.computeValues();
-    NodeList<CompilationUnitMember> members = unit.declarations;
-    expect(members, hasLength(3));
-    _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
-    _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
-    _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
+    try {
+      Source librarySource = addSource(r'''
+  const int a = c;
+  const int b = a;
+  const int c = b;''');
+      LibraryElement libraryElement = resolve2(librarySource);
+      CompilationUnit unit =
+          analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+      analysisContext.computeErrors(librarySource);
+      expect(unit, isNotNull);
+      ConstantValueComputer computer = _makeConstantValueComputer();
+      computer.add(unit, librarySource, librarySource);
+      computer.computeValues();
+      NodeList<CompilationUnitMember> members = unit.declarations;
+      expect(members, hasLength(3));
+      _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
+      _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
+      _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
+    } finally {
+      AnalysisEngine.instance.logger = Logger.NULL;
+    }
   }
 
   void test_computeValues_dependentVariables() {
@@ -1332,23 +1333,19 @@
     _assertIntField(fields, "k", 13);
   }
 
-  void
-      test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
+  void test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(false, true, true);
   }
 
-  void
-      test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
+  void test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(false, true, false);
   }
 
-  void
-      test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
+  void test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(false, false, true);
   }
 
-  void
-      test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
+  void test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(false, false, false);
   }
 
@@ -1441,23 +1438,19 @@
     _assertIntField(fields, "x", 42);
   }
 
-  void
-      test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
+  void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(true, true, true);
   }
 
-  void
-      test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
+  void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(true, true, false);
   }
 
-  void
-      test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
+  void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(true, false, true);
   }
 
-  void
-      test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
+  void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(true, false, false);
   }
 
@@ -4864,8 +4857,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -4893,8 +4886,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration2(
             null,
             Keyword.FACTORY,
             AstFactory.identifier3(className),
@@ -4920,8 +4913,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -4953,8 +4946,8 @@
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
     String constructorName = "c";
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -4982,8 +4975,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -5063,8 +5056,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String parameterName = 'p';
-    DefaultFormalParameter formalParameter =
-        AstFactory.positionalFormalParameter(
+    DefaultFormalParameter formalParameter = AstFactory
+        .positionalFormalParameter(
             AstFactory.simpleFormalParameter3(parameterName),
             AstFactory.integer(0));
     formalParameter.accept(builder);
@@ -5335,7 +5328,7 @@
     PropertyAccessorElement accessor = accessors[0];
     expect(accessor, isNotNull);
     _assertHasDocRange(accessor, 50, 7);
-    expect(accessor.hasImplicitReturnType, isFalse);
+    expect(accessor.hasImplicitReturnType, isTrue);
     expect(accessor.name, "$functionName=");
     expect(declaration.element, same(accessor));
     expect(declaration.functionExpression.element, same(accessor));
@@ -5762,7 +5755,7 @@
     PropertyAccessorElement setter = field.setter;
     expect(setter, isNotNull);
     _assertHasDocRange(setter, 50, 7);
-    expect(setter.hasImplicitReturnType, isFalse);
+    expect(setter.hasImplicitReturnType, isTrue);
     expect(setter.isAbstract, isFalse);
     expect(setter.isExternal, isFalse);
     expect(setter.isSetter, isTrue);
@@ -5800,7 +5793,7 @@
     expect(field.getter, isNull);
     PropertyAccessorElement setter = field.setter;
     expect(setter, isNotNull);
-    expect(setter.hasImplicitReturnType, isFalse);
+    expect(setter.hasImplicitReturnType, isTrue);
     expect(setter.isAbstract, isTrue);
     expect(setter.isExternal, isFalse);
     expect(setter.isSetter, isTrue);
@@ -5839,7 +5832,7 @@
     expect(field.getter, isNull);
     PropertyAccessorElement setter = field.setter;
     expect(setter, isNotNull);
-    expect(setter.hasImplicitReturnType, isFalse);
+    expect(setter.hasImplicitReturnType, isTrue);
     expect(setter.isAbstract, isFalse);
     expect(setter.isExternal, isTrue);
     expect(setter.isSetter, isTrue);
@@ -6469,8 +6462,7 @@
         (obj) => obj is FunctionElement, FunctionElement, element);
   }
 
-  void
-      test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalParameter() {
+  void test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalParameter() {
     AstNode id = _findNodeIndexedIn(
         "Class",
         2,
@@ -6485,8 +6477,7 @@
         (obj) => obj is ClassElement, ClassElement, element);
   }
 
-  void
-      test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalParameter() {
+  void test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalParameter() {
     AstNode id = _findNodeIndexedIn(
         "Class",
         2,
@@ -6593,8 +6584,8 @@
     SimpleIdentifier identifier = AstFactory.identifier3("A");
     PrefixedIdentifier prefixedIdentifier =
         AstFactory.identifier4("pref", identifier);
-    InstanceCreationExpression creation =
-        AstFactory.instanceCreationExpression2(
+    InstanceCreationExpression creation = AstFactory
+        .instanceCreationExpression2(
             Keyword.NEW, AstFactory.typeName3(prefixedIdentifier));
     // set ClassElement
     ClassElement classElement = ElementFactory.classElement2("A");
@@ -6611,8 +6602,8 @@
   void test_locate_InstanceCreationExpression_type_simpleIdentifier() {
     // prepare: new A()
     SimpleIdentifier identifier = AstFactory.identifier3("A");
-    InstanceCreationExpression creation =
-        AstFactory.instanceCreationExpression2(
+    InstanceCreationExpression creation = AstFactory
+        .instanceCreationExpression2(
             Keyword.NEW, AstFactory.typeName3(identifier));
     // set ClassElement
     ClassElement classElement = ElementFactory.classElement2("A");
@@ -8117,8 +8108,8 @@
       String name, bool isConst) {
     List<ConstructorInitializer> initializers =
         new List<ConstructorInitializer>();
-    ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration(AstFactory.identifier3(name), null,
+    ConstructorDeclaration constructorDeclaration = AstFactory
+        .constructorDeclaration(AstFactory.identifier3(name), null,
             AstFactory.formalParameterList(), initializers);
     if (isConst) {
       constructorDeclaration.constKeyword = new KeywordToken(Keyword.CONST, 0);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 349cd0a..6792467 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -35,6 +35,24 @@
     verify([source]);
   }
 
+  void test_class_type_alias_documentationComment() {
+    Source source = addSource('''
+/**
+ * Documentation
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+    computeLibrarySourceErrors(source);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    ClassElement classC = unit.element.getType('C');
+    expect(classC.documentationComment, isNotNull);
+  }
+
   void test_ambiguousExport() {
     Source source = addSource(r'''
 library L;
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 0f43183..5d304c7 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -937,6 +937,18 @@
         [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
   }
 
+  void test_enableAsync_false_1() {
+    parseAsync = false;
+    parse4("parseFunctionDeclarationStatement",
+        "foo() async {}", [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+  }
+
+  void test_enableAsync_false_2() {
+    parseAsync = false;
+    parse4("parseFunctionDeclarationStatement",
+        "foo() sync* {}", [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+  }
+
   void test_emptyEnumBody() {
     parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
         "enum E {}", [ParserErrorCode.EMPTY_ENUM_BODY]);
@@ -2647,6 +2659,11 @@
   static bool parseFunctionBodies = true;
 
   /**
+   * A flag indicating whether parser is to parse async.
+   */
+  bool parseAsync = true;
+
+  /**
    * A flag indicating whether conditional directives support should be enabled
    * for a specific test.
    */
@@ -2713,6 +2730,7 @@
     // Parse the source.
     //
     Parser parser = createParser(listener);
+    parser.parseAsync = parseAsync;
     parser.parseConditionalDirectives = enableConditionalDirectives;
     parser.parseGenericMethods = enableGenericMethods;
     parser.parseGenericMethodComments = enableGenericMethodComments;
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1f1f2a5..4722a65 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -32,6 +32,7 @@
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -397,6 +398,14 @@
     elementMap[asyncSource] = asyncLibrary;
     elementMap[htmlSource] = htmlLibrary;
     elementMap[mathSource] = mathLibrary;
+    //
+    // Set the public and export namespaces.  We don't use exports in the fake
+    // core library so public and export namespaces are the same.
+    //
+    for (LibraryElementImpl library in elementMap.values) {
+      library.exportNamespace =
+          library.publicNamespace = new PublicNamespaceBuilder().build(library);
+    }
     context.recordLibraryElements(elementMap);
     return context;
   }
@@ -11824,6 +11833,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.strongMode = true;
     resetWithOptions(options);
@@ -13020,7 +13030,145 @@
  */
 @reflectiveTest
 class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
+  void test_genericMethod_functionExpressionInvocation_explicit() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
+  var methodCall = (c.f)/*<int>*/(3);
+  var staticCall = (C.g)/*<int>*/(3);
+  var staticFieldCall = (C.h)/*<int>*/(3);
+  var topFunCall = (topF)/*<int>*/(3);
+  var topFieldCall = (topG)/*<int>*/(3);
+  var localCall = (lf)/*<int>*/(3);
+  var paramCall = (pf)/*<int>*/(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+  }
+
+  void fail_genericMethod_functionExpressionInvocation_inferred() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
+  var methodCall = (c.f)(3);
+  var staticCall = (C.g)(3);
+  var staticFieldCall = (C.h)(3);
+  var topFunCall = (topF)(3);
+  var topFieldCall = (topG)(3);
+  var localCall = (lf)(3);
+  var paramCall = (pf)(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+  }
+
+  void fail_genericMethod_functionInvocation_inferred() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodCall = c.f(3);
+  var staticCall = C.g(3);
+  var staticFieldCall = C.h(3);
+  var topFunCall = topF(3);
+  var topFieldCall = topG(3);
+  var localCall = lf(3);
+  var paramCall = pf(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+  }
+
+  void fail_genericMethod_tearoff_instantiated() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(E e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodTearOffInst = c.f/*<int>*/;
+  var staticTearOffInst = C.g/*<int>*/;
+  var staticFieldTearOffInst = C.h/*<int>*/;
+  var topFunTearOffInst = topF/*<int>*/;
+  var topFieldTearOffInst = topG/*<int>*/;
+  var localTearOffInst = lf/*<int>*/;
+  var paramTearOffInst = pf/*<int>*/;
+}
+''');
+    expect(_findIdentifier('methodTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('staticTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('staticFieldTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('topFunTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('topFieldTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('localTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('paramTearOffInst').staticType.toString(),
+        "(int) → int");
+  }
+
   void setUp() {
+    super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.strongMode = true;
     resetWithOptions(options);
@@ -13063,7 +13211,7 @@
     SimpleIdentifier f = _findIdentifier('f');
     FunctionElementImpl e = f.staticElement;
     expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.boundTypeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
     expect(e.type.typeParameters.toString(), '[]');
     expect(e.type.toString(), '<T>(T) → T');
 
@@ -13076,11 +13224,25 @@
     SimpleIdentifier f = _findIdentifier('f');
     FunctionElementImpl e = f.staticElement;
     expect(e.typeParameters.toString(), '[T extends num]');
-    expect(e.type.boundTypeParameters.toString(), '[T extends num]');
+    expect(e.type.typeFormals.toString(), '[T extends num]');
     expect(e.type.typeParameters.toString(), '[]');
     expect(e.type.toString(), '<T extends num>(T) → T');
   }
 
+  void test_genericFunction_parameter() {
+    _resolveTestUnit(r'''
+void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    ParameterElementImpl e = f.staticElement;
+    FunctionType type = e.type;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(type.typeFormals.toString(), '[T]');
+    expect(type.toString(), '<T>(T) → T');
+    FunctionType ft = type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
   void test_genericFunction_static() {
     _resolveTestUnit(r'''
 class C<E> {
@@ -13090,7 +13252,7 @@
     SimpleIdentifier f = _findIdentifier('f');
     MethodElementImpl e = f.staticElement;
     expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.boundTypeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
     // TODO(jmesserly): we could get rid of this {E/E} substitution, but it's
     // probably harmless, as E won't be used in the function (error verifier
     // checks this), and {E/E} is a no-op anyway.
@@ -13189,7 +13351,7 @@
     SimpleIdentifier f = _findIdentifier('f');
     MethodElementImpl e = f.staticElement;
     expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.boundTypeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
     expect(e.type.typeParameters.toString(), '[E]');
     expect(e.type.typeArguments.toString(), '[E]');
     expect(e.type.toString(), '<T>(E) → List<T>');
@@ -13212,8 +13374,8 @@
   var x = cOfString.f/*<int>*/('hi');
 }
 ''');
-    SimpleIdentifier f = _findIdentifier('f/*<int>*/');
-    FunctionType ft = f.staticType;
+    MethodInvocation f = _findIdentifier('f/*<int>*/').parent;
+    FunctionType ft = f.staticInvokeType;
     expect(ft.toString(), '(String) → List<int>');
     expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
 
@@ -13222,6 +13384,37 @@
         typeProvider.listType.substitute4([typeProvider.intType]));
   }
 
+  void test_genericMethod_functionInvocation_explicit() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodCall = c.f/*<int>*/(3);
+  var staticCall = C.g/*<int>*/(3);
+  var staticFieldCall = C.h/*<int>*/(3);
+  var topFunCall = topF/*<int>*/(3);
+  var topFieldCall = topG/*<int>*/(3);
+  var localCall = lf/*<int>*/(3);
+  var paramCall = pf/*<int>*/(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+  }
+
   void test_genericMethod_functionTypedParameter() {
     _resolveTestUnit(r'''
 class C<E> {
@@ -13234,7 +13427,7 @@
     SimpleIdentifier f = _findIdentifier('f');
     MethodElementImpl e = f.staticElement;
     expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.boundTypeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
     expect(e.type.typeParameters.toString(), '[E]');
     expect(e.type.typeArguments.toString(), '[E]');
     expect(e.type.toString(), '<T>((E) → T) → List<T>');
@@ -13261,10 +13454,14 @@
 }''');
 
     SimpleIdentifier map1 = _findIdentifier('map((e) => e);');
-    expect(map1.staticType.toString(), '((dynamic) → dynamic) → dynamic');
+    MethodInvocation m1 = map1.parent;
+    expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
+    expect(map1.staticType, isNull);
     expect(map1.propagatedType, isNull);
     SimpleIdentifier map2 = _findIdentifier('map((e) => 3);');
-    expect(map2.staticType.toString(), '((dynamic) → int) → int');
+    MethodInvocation m2 = map2.parent;
+    expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
+    expect(map2.staticType, isNull);
     expect(map2.propagatedType, isNull);
   }
 
@@ -13278,13 +13475,13 @@
   }
 }
 ''');
-    SimpleIdentifier f = _findIdentifier('f/*<int>*/(3);');
-    expect(f.staticType.toString(), '(int) → S');
-    FunctionType ft = f.staticType;
+    MethodInvocation f = _findIdentifier('f/*<int>*/(3);').parent;
+    expect(f.staticInvokeType.toString(), '(int) → S');
+    FunctionType ft = f.staticInvokeType;
     expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
 
-    f = _findIdentifier('f;');
-    expect(f.staticType.toString(), '<S₀>(S₀) → S');
+    SimpleIdentifier f2 = _findIdentifier('f;');
+    expect(f2.staticType.toString(), '<S₀>(S₀) → S');
   }
 
   void test_genericMethod_nestedFunctions() {
@@ -13313,7 +13510,7 @@
         _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
     MethodElementImpl e = f.staticElement;
     expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.boundTypeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
     expect(e.type.toString(), '<T>(T) → T');
 
     FunctionType ft = e.type.instantiate([typeProvider.stringType]);
@@ -13392,6 +13589,42 @@
     verify([source]);
   }
 
+  void test_genericMethod_tearoff() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(E e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodTearOff = c.f;
+  var staticTearOff = C.g;
+  var staticFieldTearOff = C.h;
+  var topFunTearOff = topF;
+  var topFieldTearOff = topG;
+  var localTearOff = lf;
+  var paramTearOff = pf;
+}
+''');
+    expect(
+        _findIdentifier('methodTearOff').staticType.toString(), "<T>(int) → T");
+    expect(
+        _findIdentifier('staticTearOff').staticType.toString(), "<T>(T) → T");
+    expect(_findIdentifier('staticFieldTearOff').staticType.toString(),
+        "<T>(T) → T");
+    expect(
+        _findIdentifier('topFunTearOff').staticType.toString(), "<T>(T) → T");
+    expect(
+        _findIdentifier('topFieldTearOff').staticType.toString(), "<T>(T) → T");
+    expect(_findIdentifier('localTearOff').staticType.toString(), "<T>(T) → T");
+    expect(_findIdentifier('paramTearOff').staticType.toString(), "<T>(T) → T");
+  }
+
   void test_pseudoGeneric_max_doubleDouble() {
     String code = r'''
 import 'dart:math';
@@ -13510,6 +13743,79 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
+  void test_setterWithDynamicTypeIsError() {
+    Source source = addSource(r'''
+class A {
+  dynamic set f(String s) => null;
+}
+dynamic set g(int x) => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+    ]);
+    verify([source]);
+  }
+
+  void test_setterWithExplicitVoidType_returningVoid() {
+    Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+  void set f(String s) => returnsVoid();
+}
+void set g(int x) => returnsVoid();
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_setterWithNoVoidType() {
+    Source source = addSource(r'''
+class A {
+  set f(String s) {
+    return '42';
+  }
+}
+set g(int x) => 42;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE
+    ]);
+    verify([source]);
+  }
+
+  void test_setterWithNoVoidType_returningVoid() {
+    Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+  set f(String s) => returnsVoid();
+}
+set g(int x) => returnsVoid();
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_setterWithOtherTypeIsError() {
+    Source source = addSource(r'''
+class A {
+  String set f(String s) => null;
+}
+Object set g(x) => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+    ]);
+    verify([source]);
+  }
+
   void test_ternaryOperator_null_left() {
     String code = r'''
 main() {
@@ -13545,6 +13851,7 @@
 class StrongModeTypePropagationTest extends ResolverTestCase {
   @override
   void setUp() {
+    super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.strongMode = true;
     resetWithOptions(options);
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index e9dfd94..9932cf8 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine, Logger;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -64,8 +65,17 @@
       resolvers.add(customResolver);
     }
     SourceFactory factory = new SourceFactory(resolvers, packages);
-    Source source = factory.resolveUri(containingSource, uri);
-    return source != null ? source.fullName : null;
+
+    expect(AnalysisEngine.instance.logger, Logger.NULL);
+    var logger = new TestLogger();
+    AnalysisEngine.instance.logger = logger;
+    try {
+      Source source = factory.resolveUri(containingSource, uri);
+      expect(logger.log, []);
+      return source != null ? source.fullName : null;
+    } finally {
+      AnalysisEngine.instance.logger = Logger.NULL;
+    }
   }
 
   Uri restorePackageUri(
@@ -122,6 +132,10 @@
               customResolver: testResolver);
           expect(uri, testResolver.uriPath);
         });
+        test('Bad package URI', () {
+          String uri = resolvePackageUri(config: '', uri: 'package:foo');
+          expect(uri, isNull);
+        });
         test('Invalid URI', () {
           // TODO(pquitslund): fix clients to handle errors appropriately
           //   CLI: print message 'invalid package file format'
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 9db703b..87b1282 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -423,9 +423,9 @@
    */
   bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
       identical(firstError.errorCode, secondError.errorCode) &&
-      firstError.offset == secondError.offset &&
-      firstError.length == secondError.length &&
-      _equalSources(firstError.source, secondError.source);
+          firstError.offset == secondError.offset &&
+          firstError.length == secondError.length &&
+          _equalSources(firstError.source, secondError.source);
 
   /**
    * Return `true` if the two sources are equivalent.
@@ -537,23 +537,18 @@
  */
 class TestLogger implements Logger {
   /**
-   * The number of error messages that were logged.
+   * All logged messages.
    */
-  int errorCount = 0;
-
-  /**
-   * The number of informational messages that were logged.
-   */
-  int infoCount = 0;
+  List<String> log = [];
 
   @override
   void logError(String message, [CaughtException exception]) {
-    errorCount++;
+    log.add("error: $message");
   }
 
   @override
   void logInformation(String message, [CaughtException exception]) {
-    infoCount++;
+    log.add("info: $message");
   }
 }
 
diff --git a/pkg/analyzer/test/src/summary/flat_buffers_test.dart b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
new file mode 100644
index 0000000..e7b7804
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
@@ -0,0 +1,235 @@
+// Copyright (c) 2016, 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 test.src.summary.flat_buffers_test;
+
+import 'package:analyzer/src/summary/flat_buffers.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(BuilderTest);
+}
+
+@reflectiveTest
+class BuilderTest {
+  void test_error_addInt32_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addInt32(0, 0);
+    }, throwsStateError);
+  }
+
+  void test_error_addOffset_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addOffset(0, new Offset(0));
+    }, throwsStateError);
+  }
+
+  void test_error_endTable_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.endTable();
+    }, throwsStateError);
+  }
+
+  void test_error_startTable_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.startTable();
+    }, throwsStateError);
+  }
+
+  void test_error_writeString_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.writeString('12345');
+    }, throwsStateError);
+  }
+
+  void test_low() {
+    Builder builder = new Builder(initialSize: 0);
+    builder.lowReset();
+    expect((builder..lowWriteUint8(1)).lowFinish(), [1]);
+    expect((builder..lowWriteUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint8(3)).lowFinish(),
+        [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint8(4)).lowFinish(),
+        [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint8(5)).lowFinish(),
+        [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint32(6)).lowFinish(),
+        [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+  }
+
+  void test_table_default() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      builder.addInt32(0, 10, 10);
+      builder.addInt32(1, 20, 10);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer object = new BufferPointer.fromBytes(byteList).derefObject();
+    // was not written, so uses the new default value
+    expect(const Int32Reader().vTableGet(object, 0, 15), 15);
+    // has the written value
+    expect(const Int32Reader().vTableGet(object, 1, 15), 20);
+  }
+
+  void test_table_types() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset<String> stringOffset = builder.writeString('12345');
+      builder.startTable();
+      builder.addBool(0, true);
+      builder.addInt8(1, 10);
+      builder.addInt32(2, 20);
+      builder.addOffset(3, stringOffset);
+      builder.addInt32(4, 40);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer object = new BufferPointer.fromBytes(byteList).derefObject();
+    expect(const BoolReader().vTableGet(object, 0), true);
+    expect(const Int8Reader().vTableGet(object, 1), 10);
+    expect(const Int32Reader().vTableGet(object, 2), 20);
+    expect(const StringReader().vTableGet(object, 3), '12345');
+    expect(const Int32Reader().vTableGet(object, 4), 40);
+  }
+
+  void test_writeList_ofInt32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<int> items = const ListReader<int>(const Int32Reader()).read(root);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
+  }
+
+  void test_writeList_ofObjects() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      // write the object #1
+      Offset object1;
+      {
+        builder.startTable();
+        builder.addInt32(0, 10);
+        builder.addInt32(1, 20);
+        object1 = builder.endTable();
+      }
+      // write the object #1
+      Offset object2;
+      {
+        builder.startTable();
+        builder.addInt32(0, 100);
+        builder.addInt32(1, 200);
+        object2 = builder.endTable();
+      }
+      // write the list
+      Offset offset = builder.writeList([object1, object2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<TestPointImpl> items =
+        const ListReader<TestPointImpl>(const TestPointReader()).read(root);
+    expect(items, hasLength(2));
+    expect(items[0].x, 10);
+    expect(items[0].y, 20);
+    expect(items[1].x, 100);
+    expect(items[1].y, 200);
+  }
+
+  void test_writeList_ofStrings_asRoot() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset<String> str1 = builder.writeString('12345');
+      Offset<String> str2 = builder.writeString('ABC');
+      Offset offset = builder.writeList([str1, str2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<String> items =
+        const ListReader<String>(const StringReader()).read(root);
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+
+  void test_writeList_ofStrings_inObject() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset listOffset = builder.writeList(
+          [builder.writeString('12345'), builder.writeString('ABC')]);
+      builder.startTable();
+      builder.addOffset(0, listOffset);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    StringListWrapperImpl reader = new StringListWrapperReader().read(root);
+    List<String> items = reader.items;
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+}
+
+class StringListWrapperImpl {
+  final BufferPointer bp;
+
+  StringListWrapperImpl(this.bp);
+
+  List<String> get items =>
+      const ListReader<String>(const StringReader()).vTableGet(bp, 0);
+}
+
+class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
+  const StringListWrapperReader();
+
+  @override
+  StringListWrapperImpl createObject(BufferPointer object) {
+    return new StringListWrapperImpl(object);
+  }
+}
+
+class TestPointImpl {
+  final BufferPointer bp;
+
+  TestPointImpl(this.bp);
+
+  int get x => const Int32Reader().vTableGet(bp, 0, 0);
+
+  int get y => const Int32Reader().vTableGet(bp, 1, 0);
+}
+
+class TestPointReader extends TableReader<TestPointImpl> {
+  const TestPointReader();
+
+  @override
+  TestPointImpl createObject(BufferPointer object) {
+    return new TestPointImpl(object);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/name_filter_test.dart b/pkg/analyzer/test/src/summary/name_filter_test.dart
new file mode 100644
index 0000000..a3c9ae5
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/name_filter_test.dart
@@ -0,0 +1,251 @@
+// Copyright (c) 2016, 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.
+
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/name_filter.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(NameFilterTest);
+}
+
+class MockUnlinkedCombinator implements UnlinkedCombinator {
+  @override
+  final List<String> hides;
+
+  @override
+  final List<String> shows;
+
+  MockUnlinkedCombinator(
+      {this.hides: const <String>[], this.shows: const <String>[]});
+
+  @override
+  Map<String, Object> toMap() {
+    fail('toMap() called unexpectedly');
+    return null;
+  }
+}
+
+@reflectiveTest
+class NameFilterTest {
+  test_accepts_accessors_hide() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['bar']));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('foo='), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('bar='), isFalse);
+  }
+
+  test_accepts_accessors_show() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo']));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('foo='), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('bar='), isFalse);
+  }
+
+  test_forNamespaceCombinator_hide() {
+    NameFilter filter = new NameFilter.forNamespaceCombinator(
+        new HideElementCombinatorImpl()..hiddenNames = ['foo', 'bar']);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forNamespaceCombinator_show() {
+    NameFilter filter = new NameFilter.forNamespaceCombinator(
+        new ShowElementCombinatorImpl()..shownNames = ['foo', 'bar']);
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forNamespaceCombinators() {
+    NameFilter filter = new NameFilter.forNamespaceCombinators([
+      new HideElementCombinatorImpl()..hiddenNames = ['foo'],
+      new HideElementCombinatorImpl()..hiddenNames = ['bar']
+    ]);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forUnlinkedCombinator_hide() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['foo', 'bar']));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forUnlinkedCombinator_show() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo', 'bar']));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forUnlinkedCombinators() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinators([
+      new MockUnlinkedCombinator(hides: ['foo']),
+      new MockUnlinkedCombinator(hides: ['bar'])
+    ]);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_identity() {
+    expect(NameFilter.identity.accepts('foo'), isTrue);
+    expect(NameFilter.identity.hiddenNames, isNotNull);
+    expect(NameFilter.identity.hiddenNames, isEmpty);
+    expect(NameFilter.identity.shownNames, isNull);
+  }
+
+  test_merge_hides_hides() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['foo'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['bar'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_hides_identity() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['foo', 'bar']))
+        .merge(NameFilter.identity);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_hides_shows() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['bar', 'baz'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['foo', 'bar'])));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo'].toSet());
+  }
+
+  test_merge_identity_hides() {
+    NameFilter filter = NameFilter.identity.merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['foo', 'bar'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_identity_identity() {
+    NameFilter filter = NameFilter.identity.merge(NameFilter.identity);
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, isEmpty);
+    expect(filter.shownNames, isNull);
+  }
+
+  test_merge_identity_shows() {
+    NameFilter filter = NameFilter.identity.merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['foo', 'bar'])));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_shows_hides() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo', 'bar'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['bar', 'baz'])));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo'].toSet());
+  }
+
+  test_merge_shows_identity() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['foo', 'bar']))
+        .merge(NameFilter.identity);
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_shows_shows() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo', 'bar'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['bar', 'baz'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['bar'].toSet());
+  }
+
+  test_merge_shows_shows_emptyResult() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['bar'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, isEmpty);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index 642b60b..c27b507 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -5,8 +5,9 @@
 library test.src.serialization.elements_test;
 
 import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart' show Namespace;
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/base.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
@@ -32,11 +33,13 @@
     otherLibrarySources.add(addNamedSource(filePath, contents));
   }
 
-  void checkLibrary(String text, {bool allowErrors: false}) {
+  void checkLibrary(String text,
+      {bool allowErrors: false, int resynthesisCount: 1}) {
     Source source = addSource(text);
     LibraryElementImpl original = resolve2(source);
-    LibraryElementImpl resynthesized =
-        resynthesizeLibrary(source, original, allowErrors);
+    LibraryElementImpl resynthesized = resynthesizeLibrary(
+        source, original, allowErrors,
+        resynthesisCount: resynthesisCount);
     checkLibraryElements(original, resynthesized);
   }
 
@@ -46,6 +49,7 @@
     expect(resynthesized.displayName, original.displayName);
     expect(original.enclosingElement, isNull);
     expect(resynthesized.enclosingElement, isNull);
+    expect(resynthesized.hasExtUri, original.hasExtUri);
     compareCompilationUnitElements(resynthesized.definingCompilationUnit,
         original.definingCompilationUnit);
     expect(resynthesized.parts.length, original.parts.length);
@@ -55,15 +59,26 @@
     expect(resynthesized.imports.length, original.imports.length);
     for (int i = 0; i < resynthesized.imports.length; i++) {
       compareImportElements(resynthesized.imports[i], original.imports[i],
-          'import ${original.imports[i].name}');
+          'import ${original.imports[i].uri}');
     }
     expect(resynthesized.exports.length, original.exports.length);
     for (int i = 0; i < resynthesized.exports.length; i++) {
       compareExportElements(resynthesized.exports[i], original.exports[i],
-          'export ${original.exports[i].name}');
+          'export ${original.exports[i].uri}');
     }
-    // TODO(paulberry): test entryPoint, exportNamespace, publicNamespace,
-    // and metadata.
+    expect(resynthesized.nameLength, original.nameLength);
+    if (original.entryPoint == null) {
+      expect(resynthesized.entryPoint, isNull);
+    } else {
+      expect(resynthesized.entryPoint, isNotNull);
+      compareFunctionElements(
+          resynthesized.entryPoint, original.entryPoint, '(entry point)');
+    }
+    compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
+        '(public namespace)');
+    compareNamespaces(resynthesized.exportNamespace, original.exportNamespace,
+        '(export namespace)');
+    // TODO(paulberry): test metadata.
   }
 
   void compareClassElements(
@@ -107,11 +122,15 @@
     for (int i = 0; i < resynthesized.accessors.length; i++) {
       String name = original.accessors[i].name;
       if (name.endsWith('=')) {
-        comparePropertyAccessorElements(resynthesized.getSetter(name),
-            original.accessors[i], '$desc.${original.accessors[i].name}=');
+        comparePropertyAccessorElements(
+            resynthesized.getSetter(name),
+            original.accessors[i],
+            '$desc setter ${original.accessors[i].name}');
       } else {
-        comparePropertyAccessorElements(resynthesized.getGetter(name),
-            original.accessors[i], '$desc.${original.accessors[i].name}');
+        comparePropertyAccessorElements(
+            resynthesized.getGetter(name),
+            original.accessors[i],
+            '$desc getter ${original.accessors[i].name}');
       }
     }
     expect(resynthesized.methods.length, original.methods.length);
@@ -124,7 +143,8 @@
 
   void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized,
       CompilationUnitElementImpl original) {
-    compareUriReferencedElements(resynthesized, original, '(compilation unit)');
+    String desc = 'Compilation unit ${original.source.uri}';
+    compareUriReferencedElements(resynthesized, original, desc);
     expect(resynthesized.source, original.source);
     expect(resynthesized.librarySource, original.librarySource);
     expect(resynthesized.types.length, original.types.length);
@@ -135,13 +155,15 @@
     expect(resynthesized.topLevelVariables.length,
         original.topLevelVariables.length);
     for (int i = 0; i < resynthesized.topLevelVariables.length; i++) {
-      compareTopLevelVariableElements(resynthesized.topLevelVariables[i],
-          original.topLevelVariables[i], original.topLevelVariables[i].name);
+      compareTopLevelVariableElements(
+          resynthesized.topLevelVariables[i],
+          original.topLevelVariables[i],
+          'variable ${original.topLevelVariables[i].name}');
     }
     expect(resynthesized.functions.length, original.functions.length);
     for (int i = 0; i < resynthesized.functions.length; i++) {
       compareFunctionElements(resynthesized.functions[i], original.functions[i],
-          original.functions[i].name);
+          'function ${original.functions[i].name}');
     }
     expect(resynthesized.functionTypeAliases.length,
         original.functionTypeAliases.length);
@@ -158,8 +180,13 @@
     }
     expect(resynthesized.accessors.length, original.accessors.length);
     for (int i = 0; i < resynthesized.accessors.length; i++) {
-      comparePropertyAccessorElements(resynthesized.accessors[i],
-          original.accessors[i], original.accessors[i].name);
+      if (original.accessors[i].isGetter) {
+        comparePropertyAccessorElements(resynthesized.accessors[i],
+            original.accessors[i], 'getter ${original.accessors[i].name}');
+      } else {
+        comparePropertyAccessorElements(resynthesized.accessors[i],
+            original.accessors[i], 'setter ${original.accessors[i].name}');
+      }
     }
     // TODO(paulberry): test metadata and offsetToElementMap.
   }
@@ -176,6 +203,10 @@
     expect(resynthesized.kind, original.kind);
     expect(resynthesized.location, original.location, reason: desc);
     expect(resynthesized.name, original.name);
+    expect(resynthesized.nameOffset, original.nameOffset, reason: desc);
+    expect(resynthesized.documentationComment, original.documentationComment,
+        reason: desc);
+    expect(resynthesized.docRange, original.docRange, reason: desc);
     for (Modifier modifier in Modifier.values) {
       if (modifier == Modifier.MIXIN) {
         // Skipping for now.  TODO(paulberry): fix.
@@ -292,6 +323,19 @@
     }
   }
 
+  void compareNamespaces(
+      Namespace resynthesized, Namespace original, String desc) {
+    Map<String, Element> resynthesizedMap = resynthesized.definedNames;
+    Map<String, Element> originalMap = original.definedNames;
+    expect(resynthesizedMap.keys.toSet(), originalMap.keys.toSet(),
+        reason: desc);
+    for (String key in originalMap.keys) {
+      Element resynthesizedElement = resynthesizedMap[key];
+      Element originalElement = originalMap[key];
+      compareElements(resynthesizedElement, originalElement, key);
+    }
+  }
+
   void compareParameterElements(ParameterElementImpl resynthesized,
       ParameterElementImpl original, String desc) {
     compareVariableElements(resynthesized, original, desc);
@@ -386,6 +430,8 @@
     } else if (resynthesized is FunctionTypeImpl &&
         original is FunctionTypeImpl) {
       compareTypeImpls(resynthesized, original, desc);
+      expect(resynthesized.isInstantiated, original.isInstantiated,
+          reason: desc);
       if (original.element.isSynthetic &&
           original.element is FunctionTypeAliasElementImpl &&
           resynthesized.element is FunctionTypeAliasElementImpl) {
@@ -410,12 +456,11 @@
               original.typeParameters[i], '$desc type parameter $i');
         }
       }
-      expect(resynthesized.boundTypeParameters.length,
-          original.boundTypeParameters.length,
+      expect(resynthesized.typeFormals.length, original.typeFormals.length,
           reason: desc);
-      for (int i = 0; i < resynthesized.boundTypeParameters.length; i++) {
-        compareTypeParameterElements(resynthesized.boundTypeParameters[i],
-            original.boundTypeParameters[i], '$desc bound type parameter $i');
+      for (int i = 0; i < resynthesized.typeFormals.length; i++) {
+        compareTypeParameterElements(resynthesized.typeFormals[i],
+            original.typeFormals[i], '$desc bound type parameter $i');
       }
     } else if (resynthesized is VoidTypeImpl && original is VoidTypeImpl) {
       expect(resynthesized, same(original));
@@ -431,6 +476,8 @@
       UriReferencedElementImpl original, String desc) {
     compareElements(resynthesized, original, desc);
     expect(resynthesized.uri, original.uri);
+    expect(resynthesized.uriOffset, original.uriOffset, reason: desc);
+    expect(resynthesized.uriEnd, original.uriEnd, reason: desc);
   }
 
   void compareVariableElements(VariableElementImpl resynthesized,
@@ -440,23 +487,29 @@
     // TODO(paulberry): test initializer
   }
 
+  fail_library_hasExtUri() {
+    checkLibrary('import "dart-ext:doesNotExist.dart";');
+  }
+
   LibraryElementImpl resynthesizeLibrary(
-      Source source, LibraryElementImpl original, bool allowErrors) {
+      Source source, LibraryElementImpl original, bool allowErrors,
+      {int resynthesisCount: 1}) {
     if (!allowErrors) {
       assertNoErrors(source);
     }
     String uri = source.uri.toString();
     addLibrary('dart:core');
-    return resynthesizeLibraryElement(uri, original);
+    return resynthesizeLibraryElement(uri, original,
+        resynthesisCount: resynthesisCount);
   }
 
   LibraryElementImpl resynthesizeLibraryElement(
-      String uri, LibraryElementImpl original) {
+      String uri, LibraryElementImpl original,
+      {int resynthesisCount: 1}) {
     Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
     PrelinkedLibrary getPrelinkedSummaryFor(LibraryElement lib) {
-      BuilderContext ctx = new BuilderContext();
       LibrarySerializationResult serialized =
-          serializeLibrary(ctx, lib, typeProvider);
+          serializeLibrary(lib, typeProvider);
       for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
         unlinkedSummaries[serialized.unitUris[i]] =
             new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
@@ -493,7 +546,9 @@
     LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
     // Check that no other summaries needed to be resynthesized to resynthesize
     // the library element.
-    expect(resynthesizer.resynthesisCount, 1);
+    // TODO(paulberry): once export namespaces are resynthesized from
+    // prelinked data, resynthesisCount should be hardcoded to 1.
+    expect(resynthesizer.resynthesisCount, resynthesisCount);
     return resynthesized;
   }
 
@@ -501,6 +556,18 @@
     checkLibrary('class C = D with E, F; class D {} class E {} class F {}');
   }
 
+  test_class_alias_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+  }
+
   test_class_alias_with_forwarding_constructors() {
     addLibrarySource(
         '/a.dart',
@@ -583,6 +650,42 @@
     checkLibrary('class C { factory C() => null; }');
   }
 
+  test_class_constructor_field_formal_dynamic_dynamic() {
+    checkLibrary('class C { dynamic x; C(dynamic this.x); }');
+  }
+
+  test_class_constructor_field_formal_dynamic_typed() {
+    checkLibrary('class C { dynamic x; C(int this.x); }');
+  }
+
+  test_class_constructor_field_formal_dynamic_untyped() {
+    checkLibrary('class C { dynamic x; C(this.x); }');
+  }
+
+  test_class_constructor_field_formal_typed_dynamic() {
+    checkLibrary('class C { num x; C(dynamic this.x); }');
+  }
+
+  test_class_constructor_field_formal_typed_typed() {
+    checkLibrary('class C { num x; C(int this.x); }');
+  }
+
+  test_class_constructor_field_formal_typed_untyped() {
+    checkLibrary('class C { num x; C(this.x); }');
+  }
+
+  test_class_constructor_field_formal_untyped_dynamic() {
+    checkLibrary('class C { var x; C(dynamic this.x); }');
+  }
+
+  test_class_constructor_field_formal_untyped_typed() {
+    checkLibrary('class C { var x; C(int this.x); }');
+  }
+
+  test_class_constructor_field_formal_untyped_untyped() {
+    checkLibrary('class C { var x; C(this.x); }');
+  }
+
   test_class_constructor_implicit() {
     checkLibrary('class C {}');
   }
@@ -599,10 +702,38 @@
     checkLibrary('class C { C.foo(); C.bar(); }');
   }
 
+  test_class_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C {}''');
+  }
+
+  test_class_documented_with_references() {
+    checkLibrary('''
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {}
+
+class D {}
+class E {}''');
+  }
+
+  test_class_documented_with_windows_line_endings() {
+    checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
+  }
+
   test_class_field_const() {
     checkLibrary('class C { static const int i = 0; }');
   }
 
+  test_class_field_implicit_type() {
+    checkLibrary('class C { var x; }');
+  }
+
   test_class_field_static() {
     checkLibrary('class C { static int i; }');
   }
@@ -615,6 +746,10 @@
     checkLibrary('class C { external int get x; }');
   }
 
+  test_class_getter_implicit_return_type() {
+    checkLibrary('class C { get x => null; }');
+  }
+
   test_class_getter_static() {
     checkLibrary('class C { static int get x => null; }');
   }
@@ -659,6 +794,14 @@
     checkLibrary('class C { external void set x(int value); }');
   }
 
+  test_class_setter_implicit_param_type() {
+    checkLibrary('class C { void set x(value) {} }');
+  }
+
+  test_class_setter_implicit_return_type() {
+    checkLibrary('class C { set x(int value) {} }');
+  }
+
   test_class_setter_static() {
     checkLibrary('class C { static void set x(int value) {} }');
   }
@@ -691,6 +834,16 @@
     checkLibrary('class C {} class D {}');
   }
 
+  test_constructor_documented() {
+    checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}''');
+  }
+
   test_core() {
     String uri = 'dart:core';
     LibraryElementImpl original =
@@ -700,6 +853,25 @@
     checkLibraryElements(original, resynthesized);
   }
 
+  test_enum_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+enum E { v }''');
+  }
+
+  test_enum_value_documented() {
+    checkLibrary('''
+enum E {
+  /**
+   * Docs
+   */
+  v
+}''');
+  }
+
   test_enum_values() {
     checkLibrary('enum E { v1, v2 }');
   }
@@ -710,23 +882,64 @@
 
   test_export_hide() {
     addLibrary('dart:async');
-    checkLibrary('export "dart:async" hide Stream, Future;');
+    checkLibrary('export "dart:async" hide Stream, Future;',
+        resynthesisCount: 2);
   }
 
   test_export_multiple_combinators() {
     addLibrary('dart:async');
-    checkLibrary('export "dart:async" hide Stream show Future;');
+    checkLibrary('export "dart:async" hide Stream show Future;',
+        resynthesisCount: 2);
   }
 
   test_export_show() {
     addLibrary('dart:async');
-    checkLibrary('export "dart:async" show Future, Stream;');
+    checkLibrary('export "dart:async" show Future, Stream;',
+        resynthesisCount: 2);
   }
 
   test_exports() {
     addLibrarySource('/a.dart', 'library a;');
     addLibrarySource('/b.dart', 'library b;');
-    checkLibrary('export "a.dart"; export "b.dart";');
+    checkLibrary('export "a.dart"; export "b.dart";', resynthesisCount: 3);
+  }
+
+  test_field_documented() {
+    checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  var x;
+}''');
+  }
+
+  test_function_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+f() {}''');
+  }
+
+  test_function_entry_point() {
+    checkLibrary('main() {}');
+  }
+
+  test_function_entry_point_in_export() {
+    addLibrarySource('/a.dart', 'library a; main() {}');
+    checkLibrary('export "a.dart";', resynthesisCount: 2);
+  }
+
+  test_function_entry_point_in_export_hidden() {
+    addLibrarySource('/a.dart', 'library a; main() {}');
+    checkLibrary('export "a.dart" hide main;', resynthesisCount: 2);
+  }
+
+  test_function_entry_point_in_part() {
+    addNamedSource('/a.dart', 'part of my.lib; main() {}');
+    checkLibrary('library my.lib; part "a.dart";');
   }
 
   test_function_external() {
@@ -779,10 +992,29 @@
     checkLibrary('void f() {}');
   }
 
+  test_function_type_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('T f<T, U>(U u) => null;');
+  }
+
+  test_function_type_parameter_with_function_typed_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('void f<T, U>(T x(U u)) {}');
+  }
+
   test_functions() {
     checkLibrary('f() {} g() {}');
   }
 
+  test_getter_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+get x => null;''');
+  }
+
   test_getter_external() {
     checkLibrary('external int get x;');
   }
@@ -791,6 +1023,14 @@
     checkLibrary('int get x => null; get y => null;');
   }
 
+  test_implicitTopLevelVariable_getterFirst() {
+    checkLibrary('int get x => 0; void set x(int value) {}');
+  }
+
+  test_implicitTopLevelVariable_setterFirst() {
+    checkLibrary('void set x(int value) {} int get x => 0;');
+  }
+
   test_import_hide() {
     addLibrary('dart:async');
     checkLibrary('import "dart:async" hide Stream, Completer; Future f;');
@@ -821,14 +1061,41 @@
     checkLibrary('');
   }
 
+  test_library_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+library foo;''');
+  }
+
+  test_library_name_with_spaces() {
+    checkLibrary('library foo . bar ;');
+  }
+
   test_library_named() {
     checkLibrary('library foo.bar;');
   }
 
+  test_method_documented() {
+    checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  f() {}
+}''');
+  }
+
   test_method_parameter_parameters() {
     checkLibrary('class C { f(g(x, y)) {} }');
   }
 
+  test_method_parameter_parameters_in_generic_class() {
+    checkLibrary('class C<A, B> { f(A g(B x)) {} }');
+  }
+
   test_method_parameter_return_type() {
     checkLibrary('class C { f(int g()) {} }');
   }
@@ -837,6 +1104,21 @@
     checkLibrary('class C { f(void g()) {} }');
   }
 
+  test_method_type_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('class C { T f<T, U>(U u) => null; }');
+  }
+
+  test_method_type_parameter_in_generic_class() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('class C<T, U> { V f<V, W>(T t, U u, W w) => null; }');
+  }
+
+  test_method_type_parameter_with_function_typed_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
+  }
+
   test_operator() {
     checkLibrary('class C { C operator+(C other) => null; }');
   }
@@ -871,6 +1153,15 @@
     checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
   }
 
+  test_setter_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+void set x(value) {}''');
+  }
+
   test_setter_external() {
     checkLibrary('external void set x(int value);');
   }
@@ -1013,10 +1304,23 @@
     checkLibrary('import "dart:core" as core; core.C c;', allowErrors: true);
   }
 
+  test_typedef_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+typedef F();''');
+  }
+
   test_typedef_parameter_parameters() {
     checkLibrary('typedef F(g(x, y));');
   }
 
+  test_typedef_parameter_parameters_in_generic_class() {
+    checkLibrary('typedef F<A, B>(A g(B x));');
+  }
+
   test_typedef_parameter_return_type() {
     checkLibrary('typedef F(int g());');
   }
@@ -1073,6 +1377,19 @@
     checkLibrary('const int i = 0;');
   }
 
+  test_variable_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+var x;''');
+  }
+
+  test_variable_implicit_type() {
+    checkLibrary('var x;');
+  }
+
   test_variables() {
     checkLibrary('int i; int j;');
   }
diff --git a/pkg/analyzer/test/src/summary/summary_sdk_test.dart b/pkg/analyzer/test/src/summary/summary_sdk_test.dart
new file mode 100644
index 0000000..5ec807e
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summary_sdk_test.dart
@@ -0,0 +1,260 @@
+// Copyright (c) 2016, 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 test.src.summary.summary_sdk_test;
+
+import 'dart:io';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, CacheState;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart' show AnalysisContextTarget;
+import 'package:analyzer/task/model.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:unittest/unittest.dart';
+
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(SummarySdkAnalysisContextTest);
+}
+
+@reflectiveTest
+class SummarySdkAnalysisContextTest {
+  static String _analyzerPackagePath;
+  static bool _analyzerPackagePathInitialized = false;
+
+  static SdkBundle sdkBundle;
+
+  SummarySdkAnalysisContext context;
+
+  void setUp() {
+    _initializeSdkContext();
+  }
+
+  test_libraryResults() {
+    if (context == null) {
+      return;
+    }
+    // verify that there are at least some interesting libraries in the bundle
+    expect(sdkBundle.prelinkedLibraryUris, contains('dart:core'));
+    expect(sdkBundle.prelinkedLibraryUris, contains('dart:async'));
+    expect(sdkBundle.prelinkedLibraryUris, contains('dart:html'));
+    // verify every library
+    for (String uri in sdkBundle.prelinkedLibraryUris) {
+      // TODO(scheglov) breaks at _LibraryResynthesizer.buildImplicitTopLevelVariable
+      if (uri == 'dart:io' || uri == 'dart:_isolate_helper') {
+        continue;
+      }
+      _assertLibraryResults(uri);
+    }
+  }
+
+  test_sourceKind() {
+    if (context == null) {
+      return;
+    }
+    // libraries
+    _assertHasSourceKind('dart:core', SourceKind.LIBRARY);
+    _assertHasSourceKind('dart:async', SourceKind.LIBRARY);
+    _assertHasSourceKind('dart:math', SourceKind.LIBRARY);
+    // parts
+    _assertHasSourceKind('dart:core/bool.dart', SourceKind.PART);
+    _assertHasSourceKind('dart:async/future.dart', SourceKind.PART);
+    // unknown
+    _assertHasSourceKind('dart:no_such_library.dart', null);
+    _assertHasSourceKind('dart:core/no_such_part.dart', null);
+  }
+
+  test_typeProvider() {
+    if (context == null) {
+      return;
+    }
+    AnalysisContextTarget target = AnalysisContextTarget.request;
+    CacheEntry cacheEntry = context.getCacheEntry(target);
+    bool hasResult = context.aboutToComputeResult(cacheEntry, TYPE_PROVIDER);
+    expect(hasResult, isTrue);
+    expect(cacheEntry.getState(TYPE_PROVIDER), CacheState.VALID);
+    TypeProvider typeProvider = cacheEntry.getValue(TYPE_PROVIDER);
+    expect(typeProvider.objectType, isNotNull);
+    expect(typeProvider.boolType, isNotNull);
+    expect(typeProvider.intType, isNotNull);
+    expect(typeProvider.futureType, isNotNull);
+    expect(typeProvider.futureDynamicType, isNotNull);
+    expect(typeProvider.streamType, isNotNull);
+    expect(typeProvider.streamDynamicType, isNotNull);
+  }
+
+  void _assertHasLibraryElement(CacheEntry cacheEntry,
+      ResultDescriptor<LibraryElement> resultDescriptor) {
+    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
+    expect(hasResult, isTrue);
+    expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
+    LibraryElement library = cacheEntry.getValue(resultDescriptor);
+    expect(library, isNotNull);
+  }
+
+  void _assertHasSourceKind(String uri, SourceKind expectedValue) {
+    Source target = context.sourceFactory.forUri(uri);
+    CacheEntry cacheEntry = context.getCacheEntry(target);
+    ResultDescriptor<SourceKind> resultDescriptor = SOURCE_KIND;
+    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
+    if (expectedValue == null) {
+      expect(hasResult, isFalse);
+      expect(cacheEntry.getState(resultDescriptor), CacheState.INVALID);
+    } else {
+      expect(hasResult, isTrue);
+      expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
+      SourceKind value = cacheEntry.getValue(resultDescriptor);
+      expect(value, expectedValue);
+    }
+  }
+
+  void _assertIsLibraryElementReady(
+      CacheEntry cacheEntry, ResultDescriptor<bool> resultDescriptor) {
+    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
+    expect(hasResult, isTrue);
+    expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
+    bool ready = cacheEntry.getValue(resultDescriptor);
+    expect(ready, isTrue);
+  }
+
+  void _assertLibraryResults(String uri) {
+    Source target = context.sourceFactory.forUri(uri);
+    CacheEntry cacheEntry = context.getCacheEntry(target);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT1);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT2);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT3);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT4);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT5);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT6);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT7);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT8);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT);
+    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT2);
+    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT5);
+    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT6);
+  }
+
+  void _initializeSdkBundle() {
+    if (sdkBundle != null) {
+      return;
+    }
+    // prepare analyzer path
+    String analyzerPath = getAnalyzerPackagePath();
+    if (analyzerPath == null) {
+      return;
+    }
+    // prepare summary path
+    String sdkSummaryPath = pathos.join(
+        analyzerPath, 'test', 'src', 'summary', 'sdk_analysis_summary');
+    File file = new File(sdkSummaryPath);
+    if (!file.existsSync()) {
+      return;
+    }
+    // load SdkBundle
+    List<int> bytes = file.readAsBytesSync();
+    sdkBundle = new SdkBundle.fromBuffer(bytes);
+  }
+
+  void _initializeSdkContext() {
+    _initializeSdkBundle();
+    if (sdkBundle == null) {
+      return;
+    }
+    context = new _TestSummarySdkAnalysisContext(sdkBundle);
+    DartSdk sdk = new _TestSummaryDartSdk();
+    context.sourceFactory = new SourceFactory([new DartUriResolver(sdk)]);
+  }
+
+  static String getAnalyzerPackagePath() {
+    if (!_analyzerPackagePathInitialized) {
+      _analyzerPackagePathInitialized = true;
+      _analyzerPackagePath = _computeAnalyzerPackagePath();
+    }
+    return _analyzerPackagePath;
+  }
+
+  /**
+   * Return the path to the `analyzer` package root, or `null` if it cannot
+   * be determined.
+   *
+   * This method expects that one of the `analyzer` tests was run, so
+   * [Platform.script] is inside of the `analyzer/test` folder.
+   */
+  static String _computeAnalyzerPackagePath() {
+    Uri uri = Platform.script;
+    if (uri == null || uri.scheme != 'file') {
+      return null;
+    }
+    String path = pathos.fromUri(uri);
+    List<String> segments = pathos.split(path);
+    while (segments.length > 2) {
+      if (segments[segments.length - 1] == 'test' &&
+          segments[segments.length - 2] == 'analyzer') {
+        segments.removeLast();
+        return pathos.joinAll(segments);
+      }
+      segments.removeLast();
+    }
+    return null;
+  }
+}
+
+class _TestSummaryDartSdk implements DartSdk {
+  @override
+  Source mapDartUri(String uriStr) {
+    Uri uri = Uri.parse(uriStr);
+    List<String> segments = uri.pathSegments;
+    if (segments.length == 1) {
+      String libraryName = segments.first;
+      String path = '/sdk/$libraryName/$libraryName.dart';
+      return new _TestSummarySdkSource(path, uri);
+    } else {
+      String path = '/sdk/' + segments.join('/');
+      return new _TestSummarySdkSource(path, uri);
+    }
+  }
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * [SummarySdkAnalysisContext] with simplified cache creation.
+ */
+class _TestSummarySdkAnalysisContext extends SummarySdkAnalysisContext {
+  _TestSummarySdkAnalysisContext(SdkBundle bundle) : super(bundle);
+
+  @override
+  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
+    return new AnalysisCache(<CachePartition>[new SdkCachePartition(this)]);
+  }
+}
+
+class _TestSummarySdkSource extends TestSourceWithUri {
+  _TestSummarySdkSource(String path, Uri uri) : super(path, uri);
+
+  @override
+  bool get isInSystemLibrary => true;
+
+  @override
+  Uri resolveRelativeUri(Uri relativeUri) {
+    Uri baseUri = uri;
+    if (uri.scheme == 'dart') {
+      String libraryName = uri.path;
+      baseUri = Uri.parse('dart:$libraryName/$libraryName.dart');
+    }
+    return baseUri.resolveUri(relativeUri);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
index e9d46b4..8b25e9d 100644
--- a/pkg/analyzer/test/src/summary/summary_test.dart
+++ b/pkg/analyzer/test/src/summary/summary_test.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/summary/base.dart';
 import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/prelink.dart';
 import 'package:analyzer/src/summary/public_namespace_computer.dart'
     as public_namespace;
 import 'package:analyzer/src/summary/summarize_elements.dart'
@@ -27,6 +28,157 @@
 main() {
   groupSep = ' | ';
   runReflectiveTests(SummarizeElementsTest);
+  runReflectiveTests(PrelinkerTest);
+}
+
+/**
+ * Convert a summary object (or a portion of one) into a canonical form that
+ * can be easily compared using [expect].  If [orderByName] is true, and the
+ * object is a [List], it is sorted by the `name` field of its elements.
+ */
+Object canonicalize(Object obj, {bool orderByName: false}) {
+  if (obj is SummaryClass) {
+    Map<String, Object> result = <String, Object>{};
+    obj.toMap().forEach((String key, Object value) {
+      bool orderByName = false;
+      if (obj is UnlinkedPublicNamespace && key == 'names') {
+        orderByName = true;
+      }
+      result[key] = canonicalize(value, orderByName: orderByName);
+    });
+    return result;
+  } else if (obj is List) {
+    List<Object> result = <Object>[];
+    for (Object item in obj) {
+      result.add(canonicalize(item));
+    }
+    if (orderByName) {
+      result.sort((Object a, Object b) {
+        if (a is Map && b is Map) {
+          return Comparable.compare(a['name'], b['name']);
+        } else {
+          return 0;
+        }
+      });
+    }
+    return result;
+  } else if (obj is String || obj is num || obj is bool) {
+    return obj;
+  } else {
+    return obj.toString();
+  }
+}
+
+UnlinkedPublicNamespace computePublicNamespaceFromText(
+    String text, Source source) {
+  CharacterReader reader = new CharSequenceReader(text);
+  Scanner scanner =
+      new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
+  Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
+  parser.parseGenericMethods = true;
+  CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
+  UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
+      public_namespace.computePublicNamespace(unit).toBuffer());
+  return namespace;
+}
+
+/**
+ * Override of [SummaryTest] which verifies the correctness of the prelinker by
+ * creating summaries from the element model, discarding their prelinked
+ * information, and then recreating it using the prelinker.
+ */
+@reflectiveTest
+class PrelinkerTest extends SummarizeElementsTest {
+  /**
+   * The public namespaces of the sdk are computed once so that we don't bog
+   * down the test.  Structured as a map from absolute URI to the corresponding
+   * public namespace.
+   *
+   * Note: should an exception occur during computation of this variable, it
+   * will silently be set to null to allow other tests to run.
+   */
+  static final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () {
+    try {
+      AnalysisContext analysisContext =
+          AnalysisContextFactory.contextWithCore();
+      Map<String, UnlinkedPublicNamespace> uriToNamespace =
+          <String, UnlinkedPublicNamespace>{};
+      List<LibraryElement> libraries = [
+        analysisContext.typeProvider.objectType.element.library,
+        analysisContext.typeProvider.futureType.element.library
+      ];
+      for (LibraryElement library in libraries) {
+        summarize_elements.LibrarySerializationResult serializedLibrary =
+            summarize_elements.serializeLibrary(
+                library, analysisContext.typeProvider);
+        for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) {
+          uriToNamespace[
+              serializedLibrary.unitUris[i]] = new UnlinkedUnit.fromBuffer(
+              serializedLibrary.unlinkedUnits[i].toBuffer()).publicNamespace;
+        }
+      }
+      return uriToNamespace;
+    } catch (_) {
+      return null;
+    }
+  }();
+
+  final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace =
+      <String, UnlinkedPublicNamespace>{};
+
+  @override
+  bool get expectAbsoluteUrisInDependencies => false;
+
+  @override
+  Source addNamedSource(String filePath, String contents) {
+    Source source = super.addNamedSource(filePath, contents);
+    uriToPublicNamespace[absUri(filePath)] =
+        computePublicNamespaceFromText(contents, source);
+    return source;
+  }
+
+  String resolveToAbsoluteUri(LibraryElement library, String relativeUri) {
+    Source resolvedSource =
+        analysisContext.sourceFactory.resolveUri(library.source, relativeUri);
+    if (resolvedSource == null) {
+      fail('Failed to resolve relative uri "$relativeUri"');
+    }
+    return resolvedSource.uri.toString();
+  }
+
+  @override
+  void serializeLibraryElement(LibraryElement library) {
+    super.serializeLibraryElement(library);
+    Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
+    expect(unlinkedUnits.length, unitUris.length);
+    for (int i = 1; i < unlinkedUnits.length; i++) {
+      uriToUnit[unitUris[i]] = unlinkedUnits[i];
+    }
+    UnlinkedUnit getPart(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
+      UnlinkedUnit unit = uriToUnit[absoluteUri];
+      if (unit == null) {
+        fail('Prelinker unexpectedly requested unit for "$relativeUri"'
+            ' (resolves to "$absoluteUri").');
+      }
+      return unit;
+    }
+    UnlinkedPublicNamespace getImport(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
+      UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
+      if (namespace == null) {
+        namespace = uriToPublicNamespace[absoluteUri];
+      }
+      if (namespace == null && !allowMissingFiles) {
+        fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
+            ' (resolves to "$absoluteUri").'
+            '  Namespaces available: ${uriToPublicNamespace.keys}');
+      }
+      return namespace;
+    }
+    prelinked = new PrelinkedLibrary.fromBuffer(
+        prelink(unlinkedUnits[0], getPart, getImport).toBuffer());
+  }
 }
 
 /**
@@ -34,51 +186,29 @@
  */
 @reflectiveTest
 class SummarizeElementsTest extends ResolverTestCase with SummaryTest {
-  final BuilderContext builderContext = new BuilderContext();
-
   /**
    * The list of absolute unit URIs corresponding to the compilation units in
    * [unlinkedUnits].
    */
   List<String> unitUris;
 
+  /**
+   * Map containing all source files in this test, and their corresponding file
+   * contents.
+   */
+  final Map<Source, String> _fileContents = <Source, String>{};
+
   @override
   bool get checkAstDerivedData => false;
 
-  /**
-   * Convert a summary object (or a portion of one) into a canonical form that
-   * can be easily compared using [expect].  If [orderByName] is true, and the
-   * object is a [List], it is sorted by the `name` field of its elements.
-   */
-  Object canonicalize(Object obj, {bool orderByName: false}) {
-    if (obj is SummaryClass) {
-      Map<String, Object> result = <String, Object>{};
-      obj.toMap().forEach((String key, Object value) {
-        bool orderByName = false;
-        if (obj is UnlinkedPublicNamespace && key == 'names') {
-          orderByName = true;
-        }
-        result[key] = canonicalize(value, orderByName: orderByName);
-      });
-      return result;
-    } else if (obj is List) {
-      List<Object> result = <Object>[];
-      for (Object item in obj) {
-        result.add(canonicalize(item));
-      }
-      if (orderByName) {
-        result.sort((Object a, Object b) {
-          if (a is Map && b is Map) {
-            return Comparable.compare(a['name'], b['name']);
-          } else {
-            return 0;
-          }
-        });
-      }
-      return result;
-    } else {
-      return obj;
-    }
+  @override
+  bool get expectAbsoluteUrisInDependencies => true;
+
+  @override
+  Source addNamedSource(String filePath, String contents) {
+    Source source = super.addNamedSource(filePath, contents);
+    _fileContents[source] = contents;
+    return source;
   }
 
   /**
@@ -96,20 +226,22 @@
    */
   void serializeLibraryElement(LibraryElement library) {
     summarize_elements.LibrarySerializationResult serializedLib =
-        summarize_elements.serializeLibrary(
-            builderContext, library, typeProvider);
-    prelinked =
-        new PrelinkedLibrary.fromBuffer(serializedLib.prelinked.toBuffer());
-    unlinkedUnits = serializedLib.unlinkedUnits
-        .map((UnlinkedUnitBuilder b) =>
-            new UnlinkedUnit.fromBuffer(b.toBuffer()))
-        .toList();
+        summarize_elements.serializeLibrary(library, typeProvider);
+    {
+      List<int> buffer = serializedLib.prelinked.toBuffer();
+      prelinked = new PrelinkedLibrary.fromBuffer(buffer);
+    }
+    unlinkedUnits = serializedLib.unlinkedUnits.map((UnlinkedUnitBuilder b) {
+      List<int> buffer = b.toBuffer();
+      return new UnlinkedUnit.fromBuffer(buffer);
+    }).toList();
     unitUris = serializedLib.unitUris;
   }
 
   @override
   void serializeLibraryText(String text, {bool allowErrors: false}) {
     Source source = addSource(text);
+    _fileContents[source] = text;
     LibraryElement library = resolve2(source);
     if (!allowErrors) {
       assertNoErrors(source);
@@ -146,20 +278,19 @@
   void verifyPublicNamespace() {
     for (int i = 0; i < unlinkedUnits.length; i++) {
       Source source = analysisContext.sourceFactory.forUri(unitUris[i]);
-      String text = analysisContext.getContents(source).data;
-      CharacterReader reader = new CharSequenceReader(text);
-      Scanner scanner =
-          new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
-      Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
-      parser.parseGenericMethods = true;
-      CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
-      UnlinkedPublicNamespace namespace =
-          new UnlinkedPublicNamespace.fromBuffer(public_namespace
-              .computePublicNamespace(builderContext, unit)
-              .toBuffer());
-      expect(canonicalize(namespace),
-          canonicalize(unlinkedUnits[i].publicNamespace),
-          reason: 'publicNamespace(${unitUris[i]})');
+      String text = _fileContents[source];
+      if (text == null) {
+        if (!allowMissingFiles) {
+          fail('Could not find file while verifying public namespace: '
+              '${unitUris[i]}');
+        }
+      } else {
+        UnlinkedPublicNamespace namespace =
+            computePublicNamespaceFromText(text, source);
+        expect(canonicalize(namespace),
+            canonicalize(unlinkedUnits[i].publicNamespace),
+            reason: 'publicNamespace(${unitUris[i]})');
+      }
     }
   }
 }
@@ -184,6 +315,12 @@
   List<UnlinkedUnit> unlinkedUnits;
 
   /**
+   * A test will set this to `true` if it contains `import`, `export`, or
+   * `part` declarations that deliberately refer to non-existent files.
+   */
+  bool allowMissingFiles = false;
+
+  /**
    * `true` if the summary was created directly from the AST (and hence
    * contains information that is not obtainable from the element model alone).
    * TODO(paulberry): modify the element model so that it contains all the data
@@ -197,6 +334,13 @@
   PrelinkedUnit get definingUnit => prelinked.units[0];
 
   /**
+   * `true` if the prelinked portion of the summary is expected to contain
+   * absolute URIs.  This happens because the element model doesn't (yet) store
+   * enough information to recover relative URIs, TODO(paulberry): fix this.
+   */
+  bool get expectAbsoluteUrisInDependencies;
+
+  /**
    * Convert [path] to a suitably formatted absolute path URI for the current
    * platform.
    */
@@ -208,14 +352,14 @@
    * Add the given source file so that it may be referenced by the file under
    * test.
    */
-  addNamedSource(String filePath, String contents);
+  Source addNamedSource(String filePath, String contents);
 
   /**
    * Verify that the [dependency]th element of the dependency table represents
    * a file reachable via the given [absoluteUri] and [relativeUri].
    */
   void checkDependency(int dependency, String absoluteUri, String relativeUri) {
-    if (!checkAstDerivedData) {
+    if (expectAbsoluteUrisInDependencies) {
       // The element model doesn't (yet) store enough information to recover
       // relative URIs, so we have to use the absolute URI.
       // TODO(paulberry): fix this.
@@ -226,6 +370,44 @@
   }
 
   /**
+   * Verify that the given [dependency] lists the given [absoluteUris] or
+   * [relativeUris] as its parts.
+   */
+  void checkDependencyParts(PrelinkedDependency dependency,
+      List<String> absoluteUris, List<String> relativeUris) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUris = absoluteUris;
+    }
+    expect(dependency.parts, relativeUris);
+  }
+
+  /**
+   * Check that the given [documentationComment] matches the first
+   * Javadoc-style comment found in [text].
+   *
+   * Note that the algorithm for finding the Javadoc-style comment in [text] is
+   * a simple-minded text search; it is easily confused by corner cases such as
+   * strings containing comments, nested comments, etc.
+   */
+  void checkDocumentationComment(
+      UnlinkedDocumentationComment documentationComment, String text) {
+    expect(documentationComment, isNotNull);
+    int commentStart = text.indexOf('/*');
+    expect(commentStart, isNot(-1));
+    int commentEnd = text.indexOf('*/');
+    expect(commentEnd, isNot(-1));
+    commentEnd += 2;
+    String expectedCommentText =
+        text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n');
+    expect(documentationComment.text, expectedCommentText);
+    expect(documentationComment.offset, commentStart);
+    expect(documentationComment.length, commentEnd - commentStart);
+  }
+
+  /**
    * Verify that the given [typeRef] represents the type `dynamic`.
    */
   void checkDynamicTypeRef(UnlinkedTypeRef typeRef) {
@@ -235,20 +417,26 @@
   /**
    * Verify that the dependency table contains an entry for a file reachable
    * via the given [absoluteUri] and [relativeUri].
+   *
+   * The [PrelinkedDependency] is returned.
    */
-  void checkHasDependency(String absoluteUri, String relativeUri) {
-    if (!checkAstDerivedData) {
+  PrelinkedDependency checkHasDependency(
+      String absoluteUri, String relativeUri) {
+    if (expectAbsoluteUrisInDependencies) {
       // The element model doesn't (yet) store enough information to recover
       // relative URIs, so we have to use the absolute URI.
       // TODO(paulberry): fix this.
       relativeUri = absoluteUri;
     }
+    List<String> found = <String>[];
     for (PrelinkedDependency dep in prelinked.dependencies) {
       if (dep.uri == relativeUri) {
-        return;
+        return dep;
       }
+      found.add(dep.uri);
     }
-    fail('Did not find dependency $absoluteUri');
+    fail('Did not find dependency $relativeUri.  Found: $found');
+    return null;
   }
 
   /**
@@ -256,7 +444,7 @@
    * reachable via the given [absoluteUri] and [relativeUri].
    */
   void checkLacksDependency(String absoluteUri, String relativeUri) {
-    if (!checkAstDerivedData) {
+    if (expectAbsoluteUrisInDependencies) {
       // The element model doesn't (yet) store enough information to recover
       // relative URIs, so we have to use the absolute URI.
       // TODO(paulberry): fix this.
@@ -338,17 +526,19 @@
     if (!allowTypeParameters) {
       expect(typeRef.typeArguments, isEmpty);
     }
-    if (expectedName == null) {
+    if (expectedKind == PrelinkedReferenceKind.unresolved) {
+      // summarize_elements.dart isn't yet able to record the name of
+      // unresolved references.  TODO(paulberry): fix this.
+      expect(reference.name, '*unresolved*');
+    } else if (expectedName == null) {
       expect(reference.name, isEmpty);
     } else {
       expect(reference.name, expectedName);
     }
-    if (checkAstDerivedData) {
-      if (expectedPrefix == null) {
-        expect(reference.prefixReference, 0);
-      } else {
-        checkPrefix(reference.prefixReference, expectedPrefix);
-      }
+    if (expectedPrefix == null) {
+      expect(reference.prefixReference, 0);
+    } else {
+      checkPrefix(reference.prefixReference, expectedPrefix);
     }
     expect(referenceResolution.kind, expectedKind);
     expect(referenceResolution.unit, expectedTargetUnit);
@@ -368,11 +558,26 @@
         expectedKind: PrelinkedReferenceKind.unresolved);
   }
 
+  fail_enum_value_documented() {
+    // TODO(paulberry): currently broken because of dartbug.com/25385
+    String text = '''
+enum E {
+  /**
+   * Docs
+   */
+  v
+}''';
+    UnlinkedEnumValue value = serializeEnumText(text).values[0];
+    expect(value.documentationComment, isNotNull);
+    checkDocumentationComment(value.documentationComment, text);
+  }
+
   fail_test_import_missing() {
     // TODO(paulberry): At the moment unresolved imports are not included in
     // the element model, so we can't pass this test.
     // Unresolved imports are included since this is necessary for proper
     // dependency tracking.
+    allowMissingFiles = true;
     serializeLibraryText('import "foo.dart";', allowErrors: true);
     // Second import is the implicit import of dart:core
     expect(unlinkedUnits[0].imports, hasLength(2));
@@ -380,6 +585,44 @@
         prelinked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
   }
 
+  fail_type_reference_to_nonexistent_file_via_prefix() {
+    // TODO(paulberry): this test currently fails because there is not enough
+    // information in the element model to figure out that the unresolved
+    // reference `p.C` uses the prefix `p`.
+    allowMissingFiles = true;
+    UnlinkedTypeRef typeRef = serializeTypeText('p.C',
+        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, 'p', 'C');
+  }
+
+  fail_type_reference_to_type_visible_via_multiple_import_prefixes() {
+    // TODO(paulberry): this test currently fails because the element model
+    // doesn't record enough information to track which prefix is used to refer
+    // to a type.
+    addNamedSource('/lib1.dart', 'class C');
+    addNamedSource('/lib2.dart', 'export "lib1.dart";');
+    addNamedSource('/lib3.dart', 'export "lib1.dart";');
+    addNamedSource('/lib4.dart', 'export "lib1.dart";');
+    serializeLibraryText('''
+import 'lib2.dart';
+import 'lib3.dart' as a;
+import 'lib4.dart' as b;
+C c2;
+a.C c3;
+b.C c4;''');
+    // Note: it is important that each reference to class C records the prefix
+    // used to find it; otherwise it's possible that relinking might produce an
+    // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart.
+    checkTypeRef(
+        findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C');
+    checkTypeRef(
+        findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
+        expectedPrefix: 'a');
+    checkTypeRef(
+        findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
+        expectedPrefix: 'b');
+  }
+
   /**
    * Find the class with the given [className] in the summary, and return its
    * [UnlinkedClass] data structure.  If [unit] is not given, the class is
@@ -561,8 +804,7 @@
   UnlinkedTypeRef serializeTypeText(String text,
       {String otherDeclarations: '', bool allowErrors: false}) {
     return serializeVariableText('$otherDeclarations\n$text v;',
-            allowErrors: allowErrors)
-        .type;
+        allowErrors: allowErrors).type;
   }
 
   /**
@@ -722,6 +964,22 @@
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         PrelinkedReferenceKind.classOrEnum);
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_class_alias_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
   }
 
   test_class_alias_flag() {
@@ -730,6 +988,11 @@
     expect(cls.isMixinApplication, true);
   }
 
+  test_class_alias_generic() {
+    serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2);
+  }
+
   test_class_alias_mixin_order() {
     UnlinkedClass cls = serializeClassText('''
 class C = D with E, F;
@@ -788,6 +1051,41 @@
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         PrelinkedReferenceKind.classOrEnum);
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_class_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_documented_with_references() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {}
+
+class D {}
+class E {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_documented_with_with_windows_line_endings() {
+    String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
   }
 
   test_class_interface() {
@@ -834,6 +1132,7 @@
     var classText = 'class C {}';
     UnlinkedClass cls = serializeClassText(classText);
     expect(cls.name, 'C');
+    expect(cls.nameOffset, classText.indexOf('C'));
   }
 
   test_class_no_flags() {
@@ -916,18 +1215,23 @@
   }
 
   test_class_type_param_no_bound() {
-    UnlinkedClass cls = serializeClassText('class C<T> {}');
+    String text = 'class C<T> {}';
+    UnlinkedClass cls = serializeClassText(text);
     expect(cls.typeParameters, hasLength(1));
     expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
     expect(cls.typeParameters[0].bound, isNull);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
   }
 
   test_constructor() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
+    String text = 'class C { C(); }';
+    UnlinkedExecutable executable =
+        findExecutable('', executables: serializeClassText(text).executables);
     expect(executable.kind, UnlinkedExecutableKind.constructor);
     expect(executable.hasImplicitReturnType, isFalse);
     expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('C();'));
   }
 
   test_constructor_anonymous() {
@@ -951,6 +1255,19 @@
     expect(executable.isExternal, isTrue);
   }
 
+  test_constructor_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}''';
+    UnlinkedExecutable executable = serializeClassText(text).executables[0];
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
   test_constructor_external() {
     UnlinkedExecutable executable = findExecutable('',
         executables:
@@ -1107,9 +1424,11 @@
   }
 
   test_constructor_named() {
+    String text = 'class C { C.foo(); }';
     UnlinkedExecutable executable = findExecutable('foo',
-        executables: serializeClassText('class C { C.foo(); }').executables);
+        executables: serializeClassText(text).executables);
     expect(executable.name, 'foo');
+    expect(executable.nameOffset, text.indexOf('foo'));
   }
 
   test_constructor_non_const() {
@@ -1127,28 +1446,20 @@
   test_constructor_return_type() {
     UnlinkedExecutable executable = findExecutable('',
         executables: serializeClassText('class C { C(); }').executables);
-    checkTypeRef(executable.returnType, null, null, 'C');
+    expect(executable.returnType, isNull);
   }
 
   test_constructor_return_type_parameterized() {
     UnlinkedExecutable executable = findExecutable('',
         executables: serializeClassText('class C<T, U> { C(); }').executables);
-    checkTypeRef(executable.returnType, null, null, 'C',
-        allowTypeParameters: true, numTypeParameters: 2);
-    expect(executable.returnType.typeArguments, hasLength(2));
-    {
-      UnlinkedTypeRef typeRef = executable.returnType.typeArguments[0];
-      checkParamTypeRef(typeRef, 2);
-    }
-    {
-      UnlinkedTypeRef typeRef = executable.returnType.typeArguments[1];
-      checkParamTypeRef(typeRef, 1);
-    }
+    expect(executable.returnType, isNull);
   }
 
   test_dependencies_export_none() {
     // Exports are not listed as dependencies since no change to the exported
     // file can change the summary of the exporting file.
+    // TODO(paulberry): this needs to change since the element model for a
+    // library includes its export namespace.
     addNamedSource('/a.dart', 'library a; export "b.dart";');
     addNamedSource('/b.dart', 'library b;');
     serializeLibraryText('export "a.dart";');
@@ -1174,17 +1485,17 @@
     checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
     // The main test library depends on b.dart, because names defined in
     // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'), '/a/b/b.dart');
+    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
   }
 
   test_dependencies_import_to_export_in_subdirs_absolute_import() {
     addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
     addNamedSource('/a/b/b.dart', 'library b;');
     serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
-    checkHasDependency(absUri('/a/a.dart'), '/a/a.dart');
+    checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart'));
     // The main test library depends on b.dart, because names defined in
     // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'), '/a/b/b.dart');
+    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
   }
 
   test_dependencies_import_to_export_in_subdirs_relative() {
@@ -1229,6 +1540,32 @@
     checkLacksDependency(absUri('/b.dart'), 'b.dart');
   }
 
+  test_dependencies_parts() {
+    addNamedSource(
+        '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}');
+    addNamedSource('/b.dart', 'part of a;');
+    addNamedSource('/c.dart', 'part of a;');
+    serializeLibraryText('import "a.dart"; A a;');
+    PrelinkedDependency dep = checkHasDependency(absUri('/a.dart'), 'a.dart');
+    checkDependencyParts(
+        dep, [absUri('/b.dart'), absUri('/c.dart')], ['b.dart', 'c.dart']);
+  }
+
+  test_dependencies_parts_relative_to_importing_library() {
+    addNamedSource('/a/b.dart', 'export "c/d.dart";');
+    addNamedSource('/a/c/d.dart',
+        'library d; part "e/f.dart"; part "g/h.dart"; class D {}');
+    addNamedSource('/a/c/e/f.dart', 'part of d;');
+    addNamedSource('/a/c/g/h.dart', 'part of d;');
+    serializeLibraryText('import "a/b.dart"; D d;');
+    PrelinkedDependency dep =
+        checkHasDependency(absUri('/a/c/d.dart'), 'a/c/d.dart');
+    checkDependencyParts(
+        dep,
+        [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')],
+        ['a/c/e/f.dart', 'a/c/g/h.dart']);
+  }
+
   test_elements_in_part() {
     addNamedSource(
         '/part1.dart',
@@ -1251,14 +1588,30 @@
   }
 
   test_enum() {
-    UnlinkedEnum e = serializeEnumText('enum E { v1 }');
+    String text = 'enum E { v1 }';
+    UnlinkedEnum e = serializeEnumText(text);
     expect(e.name, 'E');
+    expect(e.nameOffset, text.indexOf('E'));
     expect(e.values, hasLength(1));
     expect(e.values[0].name, 'v1');
+    expect(e.values[0].nameOffset, text.indexOf('v1'));
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         PrelinkedReferenceKind.classOrEnum);
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_enum_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+enum E { v }''';
+    UnlinkedEnum enm = serializeEnumText(text);
+    expect(enm.documentationComment, isNotNull);
+    checkDocumentationComment(enm.documentationComment, text);
   }
 
   test_enum_order() {
@@ -1286,15 +1639,18 @@
   }
 
   test_executable_function() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    String text = '  f() {}';
+    UnlinkedExecutable executable = serializeExecutableText(text);
     expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
     expect(executable.hasImplicitReturnType, isTrue);
     checkDynamicTypeRef(executable.returnType);
     expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         PrelinkedReferenceKind.other);
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
   }
 
   test_executable_function_explicit_return() {
@@ -1315,10 +1671,12 @@
   }
 
   test_executable_getter() {
-    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
+    String text = 'int get f => 1;';
+    UnlinkedExecutable executable = serializeExecutableText(text);
     expect(executable.kind, UnlinkedExecutableKind.getter);
     expect(executable.hasImplicitReturnType, isFalse);
     expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
     expect(findVariable('f'), isNull);
     expect(findExecutable('f='), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
@@ -1396,7 +1754,6 @@
     UnlinkedExecutable executable =
         findExecutable('f=', executables: cls.executables, failIfAbsent: true);
     expect(executable.kind, UnlinkedExecutableKind.setter);
-    // For setters, hasImplicitReturnType is always false.
     expect(executable.hasImplicitReturnType, isFalse);
     expect(executable.isExternal, isFalse);
     expect(findVariable('f', variables: cls.fields), isNull);
@@ -1415,7 +1772,7 @@
     UnlinkedClass cls = serializeClassText('class C { set f(value) {} }');
     UnlinkedExecutable executable =
         findExecutable('f=', executables: cls.executables, failIfAbsent: true);
-    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.hasImplicitReturnType, isTrue);
     checkDynamicTypeRef(executable.returnType);
   }
 
@@ -1500,8 +1857,7 @@
 
   test_executable_operator_index_set() {
     UnlinkedExecutable executable = serializeClassText(
-            'class C { void operator[]=(int i, bool v) => null; }')
-        .executables[0];
+        'class C { void operator[]=(int i, bool v) => null; }').executables[0];
     expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
     expect(executable.name, '[]=');
     expect(executable.hasImplicitReturnType, false);
@@ -1585,9 +1941,11 @@
   }
 
   test_executable_param_name() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    String text = 'f(x) {}';
+    UnlinkedExecutable executable = serializeExecutableText(text);
     expect(executable.parameters, hasLength(1));
     expect(executable.parameters[0].name, 'x');
+    expect(executable.parameters[0].nameOffset, text.indexOf('x'));
   }
 
   test_executable_param_no_flags() {
@@ -1643,11 +2001,12 @@
   }
 
   test_executable_setter() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('void set f(value) {}', 'f=');
+    String text = 'void set f(value) {}';
+    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
     expect(executable.kind, UnlinkedExecutableKind.setter);
     expect(executable.hasImplicitReturnType, isFalse);
     expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
     expect(findVariable('f'), isNull);
     expect(findExecutable('f'), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
@@ -1665,8 +2024,7 @@
   test_executable_setter_implicit_return() {
     UnlinkedExecutable executable =
         serializeExecutableText('set f(value) {}', 'f=');
-    // For setters, hasImplicitReturnType is always false.
-    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.hasImplicitReturnType, isTrue);
     checkDynamicTypeRef(executable.returnType);
   }
 
@@ -1722,6 +2080,7 @@
   test_executable_type_param_in_parameter_function() {
     UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}');
     checkParamTypeRef(ex.parameters[0].type, 1);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
   }
 
   test_executable_type_param_in_parameter_method() {
@@ -1760,6 +2119,15 @@
     expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty);
   }
 
+  test_export_offset() {
+    String libraryText = '    export "dart:async";';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].exports[0].uriOffset,
+        libraryText.indexOf('"dart:async"'));
+    expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';'));
+    expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export'));
+  }
+
   test_export_show_order() {
     serializeLibraryText('export "dart:async" show Future, Stream;');
     expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
@@ -1801,6 +2169,19 @@
     expect(variable.isConst, isTrue);
   }
 
+  test_field_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  var v;
+}''';
+    UnlinkedVariable variable = serializeClassText(text).fields[0];
+    expect(variable.documentationComment, isNotNull);
+    checkDocumentationComment(variable.documentationComment, text);
+  }
+
   test_field_final() {
     UnlinkedVariable variable =
         serializeClassText('class C { final int i = 0; }').fields[0];
@@ -1813,6 +2194,18 @@
     expect(variable.isStatic, isTrue);
   }
 
+  test_function_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+f() {}''';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
   test_generic_method_in_generic_class() {
     UnlinkedClass cls = serializeClassText(
         'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
@@ -1823,6 +2216,18 @@
     checkParamTypeRef(params[3].type, 1);
   }
 
+  test_getter_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+get f => null;''';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
   test_import_deferred() {
     serializeLibraryText(
         'import "dart:async" deferred as a; main() { print(a.Future); }');
@@ -1861,6 +2266,8 @@
     expect(unlinkedUnits[0].imports, hasLength(1));
     checkDependency(prelinked.importDependencies[0], 'dart:core', 'dart:core');
     expect(unlinkedUnits[0].imports[0].uri, isEmpty);
+    expect(unlinkedUnits[0].imports[0].uriOffset, 0);
+    expect(unlinkedUnits[0].imports[0].uriEnd, 0);
     expect(unlinkedUnits[0].imports[0].prefixReference, 0);
     expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
     expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
@@ -1888,6 +2295,7 @@
   test_import_of_file_with_missing_part() {
     // Other references in foo.dart should be resolved even though foo.dart's
     // part declaration for bar.dart refers to a non-existent file.
+    allowMissingFiles = true;
     addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
     serializeLibraryText('import "foo.dart"; C x;');
     checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
@@ -1896,6 +2304,7 @@
   test_import_of_missing_export() {
     // Other references in foo.dart should be resolved even though foo.dart's
     // re-export of bar.dart refers to a non-existent file.
+    allowMissingFiles = true;
     addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
     serializeLibraryText('import "foo.dart"; C x;');
     checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
@@ -1905,6 +2314,9 @@
     String libraryText = '    import "dart:async"; Future x;';
     serializeLibraryText(libraryText);
     expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
+    expect(unlinkedUnits[0].imports[0].uriOffset,
+        libraryText.indexOf('"dart:async"'));
+    expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future'));
   }
 
   test_import_prefix_name() {
@@ -1913,6 +2325,7 @@
     // Second import is the implicit import of dart:core
     expect(unlinkedUnits[0].imports, hasLength(2));
     checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
+    expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;'));
   }
 
   test_import_prefix_none() {
@@ -1936,6 +2349,29 @@
         expectedPrefix: 'a', numTypeParameters: 1);
   }
 
+  test_import_prefixes_take_precedence_over_imported_names() {
+    addNamedSource('/a.dart', 'class b {} class A');
+    addNamedSource('/b.dart', 'class Cls {}');
+    addNamedSource('/c.dart', 'class Cls {}');
+    addNamedSource('/d.dart', 'class c {} class D');
+    serializeLibraryText('''
+import 'a.dart';
+import 'b.dart' as b;
+import 'c.dart' as c;
+import 'd.dart';
+A aCls;
+b.Cls bCls;
+c.Cls cCls;
+D dCls;
+''');
+    checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A');
+    checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls',
+        expectedPrefix: 'b');
+    checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls',
+        expectedPrefix: 'c');
+    checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D');
+  }
+
   test_import_reference() {
     UnlinkedVariable variable =
         serializeVariableText('import "dart:async"; Future v;');
@@ -1971,6 +2407,22 @@
         expectedPrefix: 'a', numTypeParameters: 1);
   }
 
+  test_import_reference_merged_prefixed_separate_libraries() {
+    addNamedSource('/a.dart', 'class A {}');
+    addNamedSource('/b.dart', 'class B {}');
+    serializeLibraryText('''
+import 'a.dart' as p;
+import 'b.dart' as p;
+
+p.A a;
+p.B b;
+''');
+    checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A',
+        expectedPrefix: 'p');
+    checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B',
+        expectedPrefix: 'p');
+  }
+
   test_import_show_order() {
     String libraryText =
         'import "dart:async" show Future, Stream; Future x; Stream y;';
@@ -1993,15 +2445,86 @@
     expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
   }
 
+  test_library_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+library foo;''';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull);
+    checkDocumentationComment(
+        unlinkedUnits[0].libraryDocumentationComment, text);
+  }
+
+  test_library_name_with_spaces() {
+    String text = 'library foo . bar ;';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryName, 'foo.bar');
+    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar'));
+    expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length);
+  }
+
   test_library_named() {
     String text = 'library foo.bar;';
     serializeLibraryText(text);
     expect(unlinkedUnits[0].libraryName, 'foo.bar');
+    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar'));
+    expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length);
   }
 
   test_library_unnamed() {
     serializeLibraryText('');
     expect(unlinkedUnits[0].libraryName, isEmpty);
+    expect(unlinkedUnits[0].libraryNameOffset, 0);
+    expect(unlinkedUnits[0].libraryNameLength, 0);
+  }
+
+  test_library_with_missing_part() {
+    // References to other parts should still be resolved.
+    allowMissingFiles = true;
+    addNamedSource('/bar.dart', 'part of my.lib; class C {}');
+    serializeLibraryText(
+        'library my.lib; part "foo.dart"; part "bar.dart"; C c;',
+        allowErrors: true);
+    checkTypeRef(findVariable('c').type, null, null, 'C',
+        expectedTargetUnit: 2);
+  }
+
+  test_local_names_take_precedence_over_imported_names() {
+    addNamedSource('/a.dart', 'class C {} class D {}');
+    serializeLibraryText('''
+import 'a.dart';
+class C {}
+C c;
+D d;''');
+    checkTypeRef(findVariable('c').type, null, null, 'C');
+    checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D');
+  }
+
+  test_method_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  f() {}
+}''';
+    UnlinkedExecutable executable = serializeClassText(text).executables[0];
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_part_declaration() {
+    addNamedSource('/a.dart', 'part of my.lib;');
+    String text = 'library my.lib; part "a.dart"; // <-part';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart');
+    expect(unlinkedUnits[0].parts, hasLength(1));
+    expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"'));
+    expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
   }
 
   test_parts_defining_compilation_unit() {
@@ -2017,7 +2540,7 @@
     serializeLibraryText(libraryText);
     expect(prelinked.units, hasLength(2));
     expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0].uri, 'part1.dart');
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart');
   }
 
   test_public_namespace_of_part() {
@@ -2028,6 +2551,18 @@
     expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C');
   }
 
+  test_setter_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+void set f(value) {}''';
+    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
   test_type_arguments_explicit() {
     UnlinkedTypeRef typeRef = serializeTypeText('List<int>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
@@ -2104,6 +2639,19 @@
         unlinkedSourceUnit: unlinkedUnits[1]);
   }
 
+  test_type_reference_from_part_withPrefix() {
+    addNamedSource('/a.dart', 'class C {}');
+    addNamedSource('/p.dart', 'part of foo; a.C v;');
+    serializeLibraryText(
+        'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";',
+        allowErrors: true);
+    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
+        absUri('/a.dart'), 'a.dart', 'C',
+        expectedPrefix: 'a',
+        prelinkedSourceUnit: prelinked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
   test_type_reference_to_class_argument() {
     UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
     {
@@ -2191,21 +2739,12 @@
         expectedTargetUnit: 1);
   }
 
-  test_type_reference_to_nonexistent_file_via_prefix() {
-    UnlinkedTypeRef typeRef = serializeTypeText('p.C',
-        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
-    checkUnresolvedTypeRef(typeRef, 'p', 'C');
-  }
-
   test_type_reference_to_part() {
     addNamedSource('/a.dart', 'part of foo; class C { C(); }');
     serializeLibraryText('library foo; part "a.dart"; C c;');
-    UnlinkedClass classA = findClass('C', unit: unlinkedUnits[1]);
-    checkTypeRef(classA.executables.single.returnType, null, null, 'C',
+    checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C',
         expectedKind: PrelinkedReferenceKind.classOrEnum,
-        expectedTargetUnit: 1,
-        prelinkedSourceUnit: prelinked.units[1],
-        unlinkedSourceUnit: unlinkedUnits[1]);
+        expectedTargetUnit: 1);
   }
 
   test_type_reference_to_typedef() {
@@ -2232,13 +2771,28 @@
     checkUnresolvedTypeRef(typeRef, null, 'Foo');
   }
 
+  test_typedef_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+typedef F();''';
+    UnlinkedTypedef typedef = serializeTypedefText(text);
+    expect(typedef.documentationComment, isNotNull);
+    checkDocumentationComment(typedef.documentationComment, text);
+  }
+
   test_typedef_name() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    String text = 'typedef F();';
+    UnlinkedTypedef type = serializeTypedefText(text);
     expect(type.name, 'F');
+    expect(type.nameOffset, text.indexOf('F'));
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         PrelinkedReferenceKind.typedef);
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
   }
 
   test_typedef_param_none() {
@@ -2281,6 +2835,7 @@
   test_typedef_type_param_in_parameter() {
     UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
     checkParamTypeRef(type.parameters[0].type, 1);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
   }
 
   test_typedef_type_param_in_return_type() {
@@ -2301,16 +2856,20 @@
   }
 
   test_variable() {
-    serializeVariableText('int i;', variableName: 'i');
+    String text = 'int i;';
+    UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
+    expect(v.nameOffset, text.indexOf('i;'));
     expect(findExecutable('i'), isNull);
     expect(findExecutable('i='), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         PrelinkedReferenceKind.other);
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
     expect(unlinkedUnits[0].publicNamespace.names[1].kind,
         PrelinkedReferenceKind.other);
     expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i=');
+    expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0);
   }
 
   test_variable_const() {
@@ -2319,6 +2878,18 @@
     expect(variable.isConst, isTrue);
   }
 
+  test_variable_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+var v;''';
+    UnlinkedVariable variable = serializeVariableText(text);
+    expect(variable.documentationComment, isNotNull);
+    checkDocumentationComment(variable.documentationComment, text);
+  }
+
   test_variable_explicit_dynamic() {
     UnlinkedVariable variable = serializeVariableText('dynamic v;');
     checkDynamicTypeRef(variable.type);
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 189d00f..252c95f 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -7,14 +7,20 @@
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
+import 'flat_buffers_test.dart' as flat_buffers_test;
+import 'name_filter_test.dart' as name_filter_test;
 import 'resynthesize_test.dart' as resynthesize_test;
+import 'summary_sdk_test.dart' as summary_sdk_test;
 import 'summary_test.dart' as summary_test;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
   group('summary tests', () {
+    flat_buffers_test.main();
+    name_filter_test.main();
     resynthesize_test.main();
+    summary_sdk_test.main();
     summary_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index b81e72a..23930d8 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -2993,6 +2993,41 @@
     expect(outputs[UNITS], hasLength(1));
   }
 
+  test_perform_enableAsync_false() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableAsync = false;
+    prepareAnalysisContext(options);
+    _performParseTask(r'''
+import 'dart:async';
+class B {void foo() async {}}''');
+    expect(outputs, hasLength(9));
+    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
+    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
+    expect(outputs[INCLUDED_PARTS], hasLength(0));
+    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
+    expect(outputs[PARSE_ERRORS], hasLength(1));
+    expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(1));
+  }
+
+  test_perform_enableAsync_true() {
+    _performParseTask(r'''
+import 'dart:async';
+class B {void foo() async {}}''');
+    expect(outputs, hasLength(9));
+    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
+    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
+    expect(outputs[INCLUDED_PARTS], hasLength(0));
+    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
+    expect(outputs[PARSE_ERRORS], hasLength(0));
+    expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(1));
+  }
+
   test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
     // Parse "lib.dart" to let the context know that "test.dart" is included.
     computeResult(
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index c3f670b..ebdca70 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -50,6 +50,23 @@
     expect(analysisOptions.strongMode, false);
   }
 
+  test_configure_enableAsync() {
+    configureContext('''
+analyzer:
+  language:
+''');
+    expect(analysisOptions.enableAsync, true);
+  }
+
+  test_configure_enableAsync_false() {
+    configureContext('''
+analyzer:
+  language:
+    enableAsync: false
+''');
+    expect(analysisOptions.enableAsync, false);
+  }
+
   test_configure_enableGenericMethods() {
     expect(analysisOptions.enableGenericMethods, false);
     configureContext('''
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index b896776..55b73a8 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -102,11 +102,9 @@
           B f = new B();
           int x;
           double y;
-          // The analyzer has what I believe is a bug (dartbug.com/23252) which
-          // causes the return type of calls to f to be treated as dynamic.
-          x = /*info:DYNAMIC_CAST should be pass*/f(3);
+          x = f(3);
           x = /*severe:STATIC_TYPE_ERROR*/f.col(3.0);
-          y = /*info:DYNAMIC_CAST should be severe:STATIC_TYPE_ERROR*/f(3);
+          y = /*severe:STATIC_TYPE_ERROR*/f(3);
           y = f.col(3.0);
           f(/*severe:STATIC_TYPE_ERROR*/3.0);
           f.col(/*severe:STATIC_TYPE_ERROR*/3);
@@ -1495,6 +1493,23 @@
        '''
   });
 
+  testChecker('null coalescing operator', {
+    '/main.dart': '''
+          class A {}
+          class C<T> {}
+          main() {
+            A a, b;
+            a ??= new A();
+            b = b ?? new A();
+
+            // downwards inference
+            C<int> c, d;
+            c ??= /*info:INFERRED_TYPE_ALLOCATION*/new C();
+            d = d ?? /*info:INFERRED_TYPE_ALLOCATION*/new C();
+          }
+       '''
+  });
+
   testChecker('compound assignments', {
     '/main.dart': '''
           class A {
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index a643e3b..d823b20 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1533,7 +1533,7 @@
       }'''
   });
 
-  group('quasi-generics', () {
+  group('generic methods', () {
     testChecker('dart:math min/max', {
       '/main.dart': '''
         import 'dart:math';
diff --git a/pkg/analyzer/tool/summary/build_sdk_summary.dart b/pkg/analyzer/tool/summary/build_sdk_summary.dart
index 52862e3..db17c57 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summary.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summary.dart
@@ -6,7 +6,6 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/base.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
 
@@ -51,14 +50,13 @@
       <PrelinkedLibraryBuilder>[];
   List<String> unlinkedUnitUris = <String>[];
   List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
-  BuilderContext builderContext = new BuilderContext();
   for (SdkLibrary lib in sdk.sdkLibraries) {
     print('Resolving and serializing: ${lib.shortName}');
     Source librarySource = sdk.mapDartUri(lib.shortName);
     LibraryElement libraryElement =
         context.computeLibraryElement(librarySource);
     LibrarySerializationResult libraryResult =
-        serializeLibrary(builderContext, libraryElement, context.typeProvider);
+        serializeLibrary(libraryElement, context.typeProvider);
     prelinkedLibraryUris.add(lib.shortName);
     prelinkedLibraries.add(libraryResult.prelinked);
     unlinkedUnitUris.addAll(libraryResult.unitUris);
@@ -67,7 +65,7 @@
   //
   // Write the whole SDK bundle.
   //
-  SdkBundleBuilder sdkBundle = encodeSdkBundle(builderContext,
+  SdkBundleBuilder sdkBundle = encodeSdkBundle(
       prelinkedLibraryUris: prelinkedLibraryUris,
       prelinkedLibraries: prelinkedLibraries,
       unlinkedUnitUris: unlinkedUnitUris,
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 9ff31d6..1918074 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -13,11 +13,9 @@
  * - A "builder" class which can be used to generate serialized summary data.
  *   This class has write-only semantics.
  *
- * Each of the "builder" classes has a single `finish` method which finalizes
- * the entity being built and returns it as an [Object].  This object should
- * only be passed to other builders (or to [BuilderContext.getBuffer]);
- * otherwise the client should treat it as opaque, since it exposes
- * implementation details of the underlying summary infrastructure.
+ * Each of the "builder" classes has a single `finish` method which writes
+ * the entity being built into the given FlatBuffer and returns the `Offset`
+ * reference to it.
  */
 library analyzer.tool.summary.generate;
 
@@ -260,8 +258,8 @@
     out();
     out('library analyzer.src.summary.format;');
     out();
-    out("import 'dart:convert';");
     out("import 'base.dart' as base;");
+    out("import 'flat_buffers.dart' as fb;");
     out();
     _idl.enums.forEach((String name, idlModel.EnumDeclaration enm) {
       outDoc(enm.documentation);
@@ -274,146 +272,18 @@
       out('}');
       out();
     });
-    _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
-      outDoc(cls.documentation);
-      out('class $name extends base.SummaryClass {');
-      indent(() {
-        for (idlModel.FieldDeclaration field in cls.fields) {
-          String fieldName = field.name;
-          idlModel.FieldType type = field.type;
-          out('${dartType(type)} _$fieldName;');
-        }
-        out();
-        out('$name.fromJson(Map json)');
-        indent(() {
-          List<String> initializers = <String>[];
-          for (idlModel.FieldDeclaration field in cls.fields) {
-            String fieldName = field.name;
-            idlModel.FieldType type = field.type;
-            String convert = 'json[${quoted(fieldName)}]';
-            if (type.isList) {
-              if (type.typeName == 'int' || type.typeName == 'String') {
-                // No conversion necessary.
-              } else {
-                convert =
-                    '$convert?.map((x) => new ${type.typeName}.fromJson(x))?.toList()';
-              }
-            } else if (_idl.classes.containsKey(type.typeName)) {
-              convert =
-                  '$convert == null ? null : new ${type.typeName}.fromJson($convert)';
-            } else if (_idl.enums.containsKey(type.typeName)) {
-              convert =
-                  '$convert == null ? null : ${type.typeName}.values[$convert]';
-            }
-            initializers.add('_$fieldName = $convert');
-          }
-          for (int i = 0; i < initializers.length; i++) {
-            String prefix = i == 0 ? ': ' : '  ';
-            String suffix = i == initializers.length - 1 ? ';' : ',';
-            out('$prefix${initializers[i]}$suffix');
-          }
-        });
-        out();
-        out('@override');
-        out('Map<String, Object> toMap() => {');
-        indent(() {
-          for (idlModel.FieldDeclaration field in cls.fields) {
-            String fieldName = field.name;
-            out('${quoted(fieldName)}: $fieldName,');
-          }
-        });
-        out('};');
-        out();
-        if (cls.isTopLevel) {
-          out('$name.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));');
-          out();
-        }
-        cls.fields.asMap().forEach((index, field) {
-          String fieldName = field.name;
-          idlModel.FieldType type = field.type;
-          if (index != 0) {
-            out();
-          }
-          String def = defaultValue(type);
-          String defaultSuffix = def == null ? '' : ' ?? $def';
-          outDoc(field.documentation);
-          out('${dartType(type)} get $fieldName => _$fieldName$defaultSuffix;');
-        });
-      });
-      out('}');
+    for (var cls in _idl.classes.values) {
+      List<String> builderParams = _generateBuilder(cls);
       out();
-      List<String> builderParams = <String>[];
-      out('class ${name}Builder {');
-      indent(() {
-        out('final Map _json = {};');
-        out();
-        out('bool _finished = false;');
-        out();
-        out('${name}Builder(base.BuilderContext context);');
-        for (idlModel.FieldDeclaration field in cls.fields) {
-          String fieldName = field.name;
-          idlModel.FieldType type = field.type;
-          out();
-          outDoc(field.documentation);
-          String conversion = '_value';
-          String condition = '';
-          if (type.isList) {
-            if (_idl.classes.containsKey(type.typeName)) {
-              conversion = '$conversion.map((b) => b.finish()).toList()';
-            } else {
-              conversion = '$conversion.toList()';
-            }
-            condition = ' || _value.isEmpty';
-          } else if (_idl.enums.containsKey(type.typeName)) {
-            conversion = '$conversion.index';
-            condition = ' || _value == ${defaultValue(type)}';
-          } else if (_idl.classes.containsKey(type.typeName)) {
-            conversion = '$conversion.finish()';
-          }
-          builderParams.add('${encodedType(type)} $fieldName');
-          out('void set $fieldName(${encodedType(type)} _value) {');
-          indent(() {
-            out('assert(!_finished);');
-            out('assert(!_json.containsKey(${quoted(fieldName)}));');
-            if (condition.isEmpty) {
-              out('if (_value != null) {');
-            } else {
-              out('if (!(_value == null$condition)) {');
-            }
-            indent(() {
-              out('_json[${quoted(fieldName)}] = $conversion;');
-            });
-            out('}');
-          });
-          out('}');
-        }
-        if (cls.isTopLevel) {
-          out();
-          out('List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));');
-        }
-        out();
-        out('Map finish() {');
-        indent(() {
-          out('assert(!_finished);');
-          out('_finished = true;');
-          out('return _json;');
-        });
-        out('}');
-      });
-      out('}');
+      _generateEncodeFunction(cls, builderParams);
       out();
-      out('${name}Builder encode$name(base.BuilderContext builderContext, {${builderParams.join(', ')}}) {');
-      indent(() {
-        out('${name}Builder builder = new ${name}Builder(builderContext);');
-        for (idlModel.FieldDeclaration field in cls.fields) {
-          String fieldName = field.name;
-          out('builder.$fieldName = $fieldName;');
-        }
-        out('return builder;');
-      });
-      out('}');
+      _generateInterface(cls);
       out();
-    });
+      _generateReader(cls);
+      out();
+      _generateImpl(cls);
+      out();
+    }
   }
 
   /**
@@ -423,6 +293,271 @@
     return JSON.encode(s);
   }
 
+  List<String> _generateBuilder(idlModel.ClassDeclaration cls) {
+    String builderName = cls.name + 'Builder';
+    List<String> builderParams = <String>[];
+    out('class $builderName {');
+    indent(() {
+      out('bool _finished = false;');
+      // Generate fields.
+      out();
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        String typeStr = encodedType(type);
+        out('$typeStr _$fieldName;');
+      }
+      // Generate constructor.
+      out();
+      out('$builderName();');
+      // Generate setters.
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        String typeStr = encodedType(field.type);
+        out();
+        outDoc(field.documentation);
+        builderParams.add('$typeStr $fieldName');
+        out('void set $fieldName($typeStr _value) {');
+        indent(() {
+          String stateFieldName = '_' + fieldName;
+          out('assert(!_finished);');
+          out('$stateFieldName = _value;');
+        });
+        out('}');
+      }
+      // Generate finish.
+      if (cls.isTopLevel) {
+        out();
+        out('List<int> toBuffer() {');
+        indent(() {
+          out('fb.Builder fbBuilder = new fb.Builder();');
+          out('return fbBuilder.finish(finish(fbBuilder));');
+        });
+        out('}');
+      }
+      out();
+      out('fb.Offset finish(fb.Builder fbBuilder) {');
+      indent(() {
+        out('assert(!_finished);');
+        out('_finished = true;');
+        // Write objects and remember Offset(s).
+        cls.fields.asMap().forEach((index, idlModel.FieldDeclaration field) {
+          idlModel.FieldType fieldType = field.type;
+          String offsetName = 'offset_' + field.name;
+          if (fieldType.isList ||
+              fieldType.typeName == 'String' ||
+              _idl.classes.containsKey(fieldType.typeName)) {
+            out('fb.Offset $offsetName;');
+          }
+        });
+        cls.fields.asMap().forEach((index, idlModel.FieldDeclaration field) {
+          idlModel.FieldType fieldType = field.type;
+          String valueName = '_' + field.name;
+          String offsetName = 'offset_' + field.name;
+          String condition;
+          String writeCode;
+          if (fieldType.isList) {
+            condition = ' || $valueName.isEmpty';
+            if (_idl.classes.containsKey(fieldType.typeName)) {
+              String itemCode = 'b.finish(fbBuilder)';
+              String listCode = '$valueName.map((b) => $itemCode).toList()';
+              writeCode = '$offsetName = fbBuilder.writeList($listCode);';
+            } else if (fieldType.typeName == 'int') {
+              writeCode = '$offsetName = fbBuilder.writeListInt32($valueName);';
+            } else {
+              assert(fieldType.typeName == 'String');
+              String itemCode = 'fbBuilder.writeString(b)';
+              String listCode = '$valueName.map((b) => $itemCode).toList()';
+              writeCode = '$offsetName = fbBuilder.writeList($listCode);';
+            }
+          } else if (fieldType.typeName == 'String') {
+            writeCode = '$offsetName = fbBuilder.writeString($valueName);';
+          } else if (_idl.classes.containsKey(fieldType.typeName)) {
+            writeCode = '$offsetName = $valueName.finish(fbBuilder);';
+          }
+          if (writeCode != null) {
+            if (condition == null) {
+              out('if ($valueName != null) {');
+            } else {
+              out('if (!($valueName == null$condition)) {');
+            }
+            indent(() {
+              out(writeCode);
+            });
+            out('}');
+          }
+        });
+        // Write the table.
+        out('fbBuilder.startTable();');
+        cls.fields.asMap().forEach((index, idlModel.FieldDeclaration field) {
+          idlModel.FieldType fieldType = field.type;
+          String valueName = '_' + field.name;
+          String condition = '$valueName != null';
+          String writeCode;
+          if (fieldType.isList ||
+              fieldType.typeName == 'String' ||
+              _idl.classes.containsKey(fieldType.typeName)) {
+            String offsetName = 'offset_' + field.name;
+            condition = '$offsetName != null';
+            writeCode = 'fbBuilder.addOffset($index, $offsetName);';
+          } else if (fieldType.typeName == 'bool') {
+            condition = '$valueName == true';
+            writeCode = 'fbBuilder.addBool($index, true);';
+          } else if (fieldType.typeName == 'int') {
+            condition += ' && $valueName != ${defaultValue(fieldType)}';
+            writeCode = 'fbBuilder.addInt32($index, $valueName);';
+          } else if (_idl.enums.containsKey(fieldType.typeName)) {
+            condition += ' && $valueName != ${defaultValue(fieldType)}';
+            writeCode = 'fbBuilder.addInt32($index, $valueName.index);';
+          }
+          if (writeCode == null) {
+            throw new UnimplementedError('Writing type ${fieldType.typeName}');
+          }
+          out('if ($condition) {');
+          indent(() {
+            out(writeCode);
+          });
+          out('}');
+        });
+        out('return fbBuilder.endTable();');
+      });
+      out('}');
+    });
+    out('}');
+    return builderParams;
+  }
+
+  void _generateEncodeFunction(
+      idlModel.ClassDeclaration cls, List<String> builderParams) {
+    String className = cls.name;
+    String builderName = className + 'Builder';
+    out('$builderName encode$className({${builderParams.join(', ')}}) {');
+    indent(() {
+      out('$builderName builder = new $builderName();');
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        out('builder.$fieldName = $fieldName;');
+      }
+      out('return builder;');
+    });
+    out('}');
+  }
+
+  void _generateImpl(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    String implName = '_${name}Impl';
+    out('class $implName implements $name {');
+    indent(() {
+      out('final fb.BufferPointer _bp;');
+      out();
+      out('$implName(this._bp);');
+      out();
+      // Write cache fields.
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String returnType = dartType(field.type);
+        String fieldName = field.name;
+        out('$returnType _$fieldName;');
+      }
+      out();
+      // Write toMap().
+      out('@override');
+      out('Map<String, Object> toMap() => {');
+      indent(() {
+        for (idlModel.FieldDeclaration field in cls.fields) {
+          String fieldName = field.name;
+          out('${quoted(fieldName)}: $fieldName,');
+        }
+      });
+      out('};');
+      // Write getters.
+      cls.fields.asMap().forEach((index, field) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        String typeName = type.typeName;
+        // Prepare "readExpr" or "readCode" + "def"
+        String readExpr;
+        String readCode;
+        String def = defaultValue(type);
+        if (type.isList) {
+          if (typeName == 'int') {
+            String itemCode = 'const fb.Int32Reader()';
+            readCode = 'const fb.ListReader<int>($itemCode)';
+          } else if (typeName == 'String') {
+            String itemCode = 'const fb.StringReader()';
+            readCode = 'const fb.ListReader<String>($itemCode)';
+          } else {
+            String itemCode = '$typeName>(const _${typeName}Reader()';
+            readCode = 'const fb.ListReader<$itemCode)';
+          }
+        } else if (typeName == 'bool') {
+          readCode = 'const fb.BoolReader()';
+        } else if (typeName == 'int') {
+          readCode = 'const fb.Int32Reader()';
+        } else if (typeName == 'String') {
+          readCode = 'const fb.StringReader()';
+        } else if (_idl.enums.containsKey(typeName)) {
+          readExpr =
+              '$typeName.values[const fb.Int32Reader().vTableGet(_bp, $index, 0)]';
+        } else if (_idl.classes.containsKey(typeName)) {
+          readCode = 'const _${typeName}Reader()';
+        }
+        if (readExpr == null) {
+          assert(readCode != null);
+          readExpr = '$readCode.vTableGet(_bp, $index, $def)';
+        }
+        // Write the getter implementation.
+        out();
+        out('@override');
+        String returnType = dartType(type);
+        out('$returnType get $fieldName {');
+        indent(() {
+          out('_$fieldName ??= $readExpr;');
+          out('return _$fieldName;');
+        });
+        out('}');
+      });
+    });
+    out('}');
+  }
+
+  void _generateInterface(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    outDoc(cls.documentation);
+    out('abstract class $name extends base.SummaryClass {');
+    indent(() {
+      if (cls.isTopLevel) {
+        out('factory $name.fromBuffer(List<int> buffer) {');
+        indent(() {
+          out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);');
+          out('return const _${name}Reader().read(rootRef);');
+        });
+        out('}');
+      }
+      cls.fields.asMap().forEach((index, field) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        out();
+        outDoc(field.documentation);
+        out('${dartType(type)} get $fieldName;');
+      });
+    });
+    out('}');
+  }
+
+  void _generateReader(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    String readerName = '_${name}Reader';
+    String implName = '_${name}Impl';
+    out('class $readerName extends fb.TableReader<$implName> {');
+    indent(() {
+      out('const $readerName();');
+      out();
+      out('@override');
+      out('$implName createObject(fb.BufferPointer bp) => new $implName(bp);');
+    });
+    out('}');
+  }
+
   /**
    * Return the documentation text of the given [node], or `null` if the [node]
    * does not have a comment.  Each line is `\n` separated.
diff --git a/pkg/analyzer/tool/summary/idl.dart b/pkg/analyzer/tool/summary/idl.dart
index 28d0da5..39e7a4a 100644
--- a/pkg/analyzer/tool/summary/idl.dart
+++ b/pkg/analyzer/tool/summary/idl.dart
@@ -68,9 +68,19 @@
  */
 class PrelinkedDependency {
   /**
-   * The relative URI used to import one library from the other.
+   * The relative URI of the dependent library.  This URI is relative to the
+   * importing library, even if there are intervening `export` declarations.
+   * So, for example, if `a.dart` imports `b/c.dart` and `b/c.dart` exports
+   * `d/e.dart`, the URI listed for `a.dart`'s dependency on `e.dart` will be
+   * `b/d/e.dart`.
    */
   String uri;
+
+  /**
+   * URI for the compilation units listed in the library's `part` declarations.
+   * These URIs are relative to the importing library.
+   */
+  List<String> parts;
 }
 
 /**
@@ -216,6 +226,19 @@
   String name;
 
   /**
+   * Offset of the class name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the class, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
+
+  /**
    * Type parameters of the class, if any.
    */
   List<UnlinkedTypeParam> typeParameters;
@@ -281,6 +304,30 @@
 }
 
 /**
+ * Unlinked summary information about a documentation comment.
+ */
+class UnlinkedDocumentationComment {
+  /**
+   * Text of the documentation comment, with '\r\n' replaced by '\n'.
+   *
+   * References appearing within the doc comment in square brackets are not
+   * specially encoded.
+   */
+  String text;
+
+  /**
+   * Offset of the beginning of the documentation comment relative to the
+   * beginning of the file.
+   */
+  int offset;
+
+  /**
+   * Length of the documentation comment (prior to replacing '\r\n' with '\n').
+   */
+  int length;
+}
+
+/**
  * Unlinked summary information about an enum declaration.
  */
 class UnlinkedEnum {
@@ -290,6 +337,19 @@
   String name;
 
   /**
+   * Offset of the enum name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the enum, or `null` if there is no documentation
+   * comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
+
+  /**
    * Values listed in the enum declaration, in declaration order.
    */
   List<UnlinkedEnumValue> values;
@@ -304,6 +364,19 @@
    * Name of the enumerated value.
    */
   String name;
+
+  /**
+   * Offset of the enum value name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the enum value, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
 }
 
 /**
@@ -319,6 +392,22 @@
   String name;
 
   /**
+   * Offset of the executable name relative to the beginning of the file.  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the offset of the class name (i.e. the
+   * offset of the second "C" in "class C { C(); }").
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the executable, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
+
+  /**
    * Type parameters of the executable, if any.  Empty if support for generic
    * method syntax is disabled.
    */
@@ -326,8 +415,8 @@
 
   /**
    * Declared return type of the executable.  Absent if the return type is
-   * `void`.  Note that when strong mode is enabled, the actual return type may
-   * be different due to type inference.
+   * `void` or the executable is a constructor.  Note that when strong mode is
+   * enabled, the actual return type may be different due to type inference.
    */
   UnlinkedTypeRef returnType;
 
@@ -406,9 +495,36 @@
 }
 
 /**
- * Unlinked summary information about an export declaration.
+ * Unlinked summary information about an export declaration (stored outside
+ * [UnlinkedPublicNamespace]).
  */
-class UnlinkedExport {
+class UnlinkedExportNonPublic {
+  /**
+   * Offset of the "export" keyword.
+   */
+  @informative
+  int offset;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  @informative
+  int uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  @informative
+  int uriEnd;
+}
+
+/**
+ * Unlinked summary information about an export declaration (stored inside
+ * [UnlinkedPublicNamespace]).
+ */
+class UnlinkedExportPublic {
   /**
    * URI used in the source code to reference the exported library.
    */
@@ -458,6 +574,27 @@
    * Indicates whether the import declaration is implicit.
    */
   bool isImplicit;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.  If [isImplicit] is true, zero.
+   */
+  @informative
+  int uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.  If [isImplicit] is true, zero.
+   */
+  @informative
+  int uriEnd;
+
+  /**
+   * Offset of the prefix name relative to the beginning of the file, or zero
+   * if there is no prefix.
+   */
+  @informative
+  int prefixOffset;
 }
 
 /**
@@ -470,6 +607,12 @@
   String name;
 
   /**
+   * Offset of the parameter name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
    * If [isFunctionTyped] is `true`, the declared return type.  If
    * [isFunctionTyped] is `false`, the declared type.  Absent if
    * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
@@ -531,9 +674,18 @@
  */
 class UnlinkedPart {
   /**
-   * String used in the compilation unit to refer to the part file.
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
    */
-  String uri;
+  @informative
+  int uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  @informative
+  int uriEnd;
 }
 
 /**
@@ -560,6 +712,12 @@
    * The kind of object referred to by the name.
    */
   PrelinkedReferenceKind kind;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int numTypeParameters;
 }
 
 /**
@@ -580,12 +738,12 @@
   /**
    * Export declarations in the compilation unit.
    */
-  List<UnlinkedExport> exports;
+  List<UnlinkedExportPublic> exports;
 
   /**
-   * Part declarations in the compilation unit.
+   * URIs referenced by part declarations in the compilation unit.
    */
-  List<UnlinkedPart> parts;
+  List<String> parts;
 }
 
 /**
@@ -602,6 +760,10 @@
   /**
    * Prefix used to refer to the entity, or zero if no prefix is used.  This is
    * an index into [UnlinkedUnit.references].
+   *
+   * Prefix references must always point backward; that is, for all i, if
+   * UnlinkedUnit.references[i].prefixReference != 0, then
+   * UnlinkedUnit.references[i].prefixReference < i.
    */
   int prefixReference;
 }
@@ -616,6 +778,19 @@
   String name;
 
   /**
+   * Offset of the typedef name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the typedef, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
+
+  /**
    * Type parameters of the typedef, if any.
    */
   List<UnlinkedTypeParam> typeParameters;
@@ -641,6 +816,12 @@
   String name;
 
   /**
+   * Offset of the type parameter name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
    * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
    * null.
    */
@@ -702,6 +883,27 @@
   String libraryName;
 
   /**
+   * Offset of the library name relative to the beginning of the file (or 0 if
+   * the library has no name).
+   */
+  @informative
+  int libraryNameOffset;
+
+  /**
+   * Length of the library name as it appears in the source code (or 0 if the
+   * library has no name).
+   */
+  @informative
+  int libraryNameLength;
+
+  /**
+   * Documentation comment for the library, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment libraryDocumentationComment;
+
+  /**
    * Unlinked public namespace of this compilation unit.
    */
   UnlinkedPublicNamespace publicNamespace;
@@ -730,11 +932,21 @@
   List<UnlinkedExecutable> executables;
 
   /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportNonPublic> exports;
+
+  /**
    * Import declarations in the compilation unit.
    */
   List<UnlinkedImport> imports;
 
   /**
+   * Part declarations in the compilation unit.
+   */
+  List<UnlinkedPart> parts;
+
+  /**
    * Typedefs declared in the compilation unit.
    */
   List<UnlinkedTypedef> typedefs;
@@ -756,6 +968,19 @@
   String name;
 
   /**
+   * Offset of the variable name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the variable, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
+
+  /**
    * Declared type of the variable.  Note that when strong mode is enabled, the
    * actual type of the variable may be different due to type inference.
    */
diff --git a/pkg/analyzer_cli/lib/src/boot_loader.dart b/pkg/analyzer_cli/lib/src/boot_loader.dart
new file mode 100644
index 0000000..6df71ae
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/boot_loader.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2015, 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 analyzer_cli.src.boot_loader;
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart' as engine;
+import 'package:analyzer/src/plugin/plugin_configuration.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:source_span/source_span.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+const _analyzerPackageName = 'analyzer';
+
+/// Return non-null if there is a validation issue with this plugin.
+String validate(PluginInfo plugin) {
+  var missing = <String>[];
+  if (plugin.className == null) {
+    missing.add('class name');
+  }
+  if (plugin.libraryUri == null) {
+    missing.add('library uri');
+  }
+  if (missing.isEmpty) {
+    // All good.
+    return null;
+  }
+  return 'Plugin ${plugin.name} skipped, config missing: ${missing.join(", ")}';
+}
+
+List<PluginInfo> _validate(Iterable<PluginInfo> plugins) {
+  List<PluginInfo> validated = <PluginInfo>[];
+  plugins.forEach((PluginInfo plugin) {
+    String validation = validate(plugin);
+    if (validation != null) {
+      errorSink.writeln(validation);
+    } else {
+      validated.add(plugin);
+    }
+  });
+  return validated;
+}
+
+/// Source code assembler.
+class Assembler {
+  /// Plugins to configure.
+  final Iterable<PluginInfo> plugins;
+
+  /// Create an assembler for the given plugin [config].
+  Assembler(this.plugins);
+
+  /// A string enumerating required package `import`s.
+  String get enumerateImports =>
+      plugins.map((PluginInfo p) => "import '${p.libraryUri}';").join('\n');
+
+  /// A string listing initialized plugin instances.
+  String get pluginList =>
+      plugins.map((PluginInfo p) => 'new ${p.className}()').join(', ');
+
+  /// Create a file containing a `main()` suitable for loading in spawned
+  /// isolate.
+  String createMain() => _generateMain();
+
+  String _generateMain() => """
+// Copyright (c) 2015, 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.
+
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+import 'package:analyzer_cli/src/driver.dart';
+
+$enumerateImports
+
+void main(List<String> args) {
+  var starter = new Driver();
+  starter.userDefinedPlugins = [$pluginList];
+  starter.start(args);
+}
+""";
+}
+
+/// Given environment information extracted from command-line `args`, creates a
+/// a loadable analyzer "image".
+class BootLoader {
+  /// Emits an error message to [errorSink] if plugin config can't be read.
+  static final ErrorHandler _pluginConfigErrorHandler = (Exception e) {
+    String details;
+    if (e is PluginConfigFormatException) {
+      details = e.message;
+      var node = e.yamlNode;
+      if (node is YamlNode) {
+        SourceLocation location = node.span.start;
+        details += ' (line ${location.line}, column ${location.column})';
+      }
+    } else {
+      details = e.toString();
+    }
+
+    errorSink.writeln('Plugin configuration skipped: $details');
+  };
+
+  /// Reads plugin config info from `.analysis_options`.
+  PluginConfigOptionsProcessor _pluginOptionsProcessor =
+      new PluginConfigOptionsProcessor(_pluginConfigErrorHandler);
+
+  /// Create a loadable analyzer image configured with plugins derived from
+  /// the given analyzer command-line `args`.
+  Image createImage(List<String> args) {
+    // Parse commandline options.
+    CommandLineOptions options = CommandLineOptions.parse(args);
+
+    // Process analysis options file (and notify all interested parties).
+    _processAnalysisOptions(options);
+
+    // TODO(pquitslund): Pass in .packages info
+    return new Image(_pluginOptionsProcessor.config,
+        args: args, packageRootPath: options.packageRootPath);
+  }
+
+  void _processAnalysisOptions(CommandLineOptions options) {
+    // Determine options file path.
+    var filePath = options.analysisOptionsFile ??
+        engine.AnalysisEngine.ANALYSIS_OPTIONS_FILE;
+    try {
+      var file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+      AnalysisOptionsProvider analysisOptionsProvider =
+          new AnalysisOptionsProvider();
+      Map<String, YamlNode> options =
+          analysisOptionsProvider.getOptionsFromFile(file);
+      //TODO(pq): thread in proper context.
+      var temporaryContext = new AnalysisContextImpl();
+      _pluginOptionsProcessor.optionsProcessed(temporaryContext, options);
+    } on Exception catch (e) {
+      _pluginOptionsProcessor.onError(e);
+    }
+  }
+}
+
+/// A loadable "image" of a a configured analyzer instance.
+class Image {
+  /// (Optional) package root path.
+  final String packageRootPath;
+
+  /// (Optional) package map.
+  final Map<String, Uri> packages;
+
+  /// (Optional) args to be passed on to the loaded main.
+  final List<String> args;
+
+  /// Plugin configuration.
+  final PluginConfig config;
+
+  /// Create an image with the given [config] and optionally [packages],
+  /// [packageRootPath], and command line [args].
+  Image(this.config, {this.packages, this.packageRootPath, this.args});
+
+  /// Load this image.
+  ///
+  /// Loading an image consists in assembling an analyzer `main()`, configured
+  /// to include the appropriate analyzer plugins as specified in
+  /// `.analyzer_options` which is then run in a spawned isolate.
+  Future load() {
+    List<PluginInfo> plugins = _validate(config.plugins);
+    String mainSource = new Assembler(plugins).createMain();
+
+    Completer completer = new Completer();
+    ReceivePort exitListener = new ReceivePort();
+    exitListener.listen((data) {
+      completer.complete();
+      exitListener.close();
+    });
+
+    Uri uri =
+        Uri.parse('data:application/dart;charset=utf-8,${Uri.encodeComponent(
+        mainSource)}');
+
+    // TODO(pquitslund): update once .packages are supported.
+    String packageRoot =
+        packageRootPath != null ? packageRootPath : './packages';
+    Uri packageUri = new Uri.file(packageRoot);
+
+    Isolate.spawnUri(uri, args, null /* msg */,
+        packageRoot: packageUri, onExit: exitListener.sendPort);
+
+    return completer.future;
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/bootloader.dart b/pkg/analyzer_cli/lib/src/bootloader.dart
deleted file mode 100644
index 726004cb3..0000000
--- a/pkg/analyzer_cli/lib/src/bootloader.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2015, 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 analyzer_cli.src.bootloader;
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/engine.dart' as engine;
-import 'package:analyzer/src/plugin/plugin_configuration.dart';
-import 'package:analyzer_cli/src/driver.dart';
-import 'package:analyzer_cli/src/options.dart';
-import 'package:source_span/source_span.dart';
-import 'package:yaml/src/yaml_node.dart';
-
-const _analyzerPackageName = 'analyzer';
-
-/// Return non-null if there is a validation issue with this plugin.
-String validate(PluginInfo plugin) {
-  var missing = <String>[];
-  if (plugin.className == null) {
-    missing.add('class name');
-  }
-  if (plugin.libraryUri == null) {
-    missing.add('library uri');
-  }
-  if (missing.isEmpty) {
-    // All good.
-    return null;
-  }
-  return 'Plugin ${plugin.name} skipped, config missing: ${missing.join(", ")}';
-}
-
-List<PluginInfo> _validate(Iterable<PluginInfo> plugins) {
-  List<PluginInfo> validated = <PluginInfo>[];
-  plugins.forEach((PluginInfo plugin) {
-    String validation = validate(plugin);
-    if (validation != null) {
-      errorSink.writeln(validation);
-    } else {
-      validated.add(plugin);
-    }
-  });
-  return validated;
-}
-
-/// Source code assembler.
-class Assembler {
-  /// Plugins to configure.
-  final Iterable<PluginInfo> plugins;
-
-  /// Create an assembler for the given plugin [config].
-  Assembler(this.plugins);
-
-  /// A string enumerating required package `import`s.
-  String get enumerateImports =>
-      plugins.map((PluginInfo p) => "import '${p.libraryUri}';").join('\n');
-
-  /// A string listing initialized plugin instances.
-  String get pluginList =>
-      plugins.map((PluginInfo p) => 'new ${p.className}()').join(', ');
-
-  /// Create a file containing a `main()` suitable for loading in spawned
-  /// isolate.
-  String createMain() => _generateMain();
-
-  String _generateMain() => """
-// Copyright (c) 2015, 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.
-
-// This code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-
-import 'package:analyzer_cli/src/driver.dart';
-
-$enumerateImports
-
-void main(List<String> args) {
-  var starter = new Driver();
-  starter.userDefinedPlugins = [$pluginList];
-  starter.start(args);
-}
-""";
-}
-
-/// Given environment information extracted from command-line `args`, creates a
-/// a loadable analyzer "image".
-class BootLoader {
-  /// Emits an error message to [errorSink] if plugin config can't be read.
-  static final ErrorHandler _pluginConfigErrorHandler = (Exception e) {
-    String details;
-    if (e is PluginConfigFormatException) {
-      details = e.message;
-      var node = e.yamlNode;
-      if (node is YamlNode) {
-        SourceLocation location = node.span.start;
-        details += ' (line ${location.line}, column ${location.column})';
-      }
-    } else {
-      details = e.toString();
-    }
-
-    errorSink.writeln('Plugin configuration skipped: $details');
-  };
-
-  /// Reads plugin config info from `.analysis_options`.
-  PluginConfigOptionsProcessor _pluginOptionsProcessor =
-      new PluginConfigOptionsProcessor(_pluginConfigErrorHandler);
-
-  /// Create a loadable analyzer image configured with plugins derived from
-  /// the given analyzer command-line `args`.
-  Image createImage(List<String> args) {
-    // Parse commandline options.
-    CommandLineOptions options = CommandLineOptions.parse(args);
-
-    // Process analysis options file (and notify all interested parties).
-    _processAnalysisOptions(options);
-
-    // TODO(pquitslund): Pass in .packages info
-    return new Image(_pluginOptionsProcessor.config,
-        args: args, packageRootPath: options.packageRootPath);
-  }
-
-  void _processAnalysisOptions(CommandLineOptions options) {
-    // Determine options file path.
-    var filePath = options.analysisOptionsFile ??
-        engine.AnalysisEngine.ANALYSIS_OPTIONS_FILE;
-    try {
-      var file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
-      AnalysisOptionsProvider analysisOptionsProvider =
-          new AnalysisOptionsProvider();
-      Map<String, YamlNode> options =
-          analysisOptionsProvider.getOptionsFromFile(file);
-      //TODO(pq): thread in proper context.
-      var temporaryContext = new AnalysisContextImpl();
-      _pluginOptionsProcessor.optionsProcessed(temporaryContext, options);
-    } on Exception catch (e) {
-      _pluginOptionsProcessor.onError(e);
-    }
-  }
-}
-
-/// A loadable "image" of a a configured analyzer instance.
-class Image {
-  /// (Optional) package root path.
-  final String packageRootPath;
-
-  /// (Optional) package map.
-  final Map<String, Uri> packages;
-
-  /// (Optional) args to be passed on to the loaded main.
-  final List<String> args;
-
-  /// Plugin configuration.
-  final PluginConfig config;
-
-  /// Create an image with the given [config] and optionally [packages],
-  /// [packageRootPath], and command line [args].
-  Image(this.config, {this.packages, this.packageRootPath, this.args});
-
-  /// Load this image.
-  ///
-  /// Loading an image consists in assembling an analyzer `main()`, configured
-  /// to include the appropriate analyzer plugins as specified in
-  /// `.analyzer_options` which is then run in a spawned isolate.
-  Future load() {
-    List<PluginInfo> plugins = _validate(config.plugins);
-    String mainSource = new Assembler(plugins).createMain();
-
-    Completer completer = new Completer();
-    ReceivePort exitListener = new ReceivePort();
-    exitListener.listen((data) {
-      completer.complete();
-      exitListener.close();
-    });
-
-    Uri uri =
-        Uri.parse('data:application/dart;charset=utf-8,${Uri.encodeComponent(
-        mainSource)}');
-
-    // TODO(pquitslund): update once .packages are supported.
-    String packageRoot =
-        packageRootPath != null ? packageRootPath : './packages';
-    Uri packageUri = new Uri.file(packageRoot);
-
-    Isolate.spawnUri(uri, args, null /* msg */,
-        packageRoot: packageUri, onExit: exitListener.sendPort);
-
-    return completer.future;
-  }
-}
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index ea55810..9f08563 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -2,6 +2,7 @@
 // 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.
 
+import 'boot_loader_test.dart' as boot_loader;
 import 'driver_test.dart' as driver;
 import 'error_test.dart' as error;
 import 'options_test.dart' as options;
@@ -13,6 +14,7 @@
 //import 'strong_mode_test.dart' as strong_mode;
 
 main() {
+  boot_loader.main();
   driver.main();
   // TODO(pq): fix tests to run safely on the bots
   // https://github.com/dart-lang/sdk/issues/25001
diff --git a/pkg/analyzer_cli/test/boot_loader_test.dart b/pkg/analyzer_cli/test/boot_loader_test.dart
new file mode 100644
index 0000000..d24d961
--- /dev/null
+++ b/pkg/analyzer_cli/test/boot_loader_test.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2016, 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 analyzer_cli.test.boot_loader_test;
+
+import 'dart:io';
+
+import 'package:analyzer/src/plugin/plugin_configuration.dart';
+import 'package:analyzer_cli/src/boot_loader.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  StringSink savedOutSink, savedErrorSink;
+  int savedExitCode;
+  ExitHandler savedExitHandler;
+
+  /// Base setup.
+  _setUp() {
+    savedOutSink = outSink;
+    savedErrorSink = errorSink;
+    savedExitHandler = exitHandler;
+    savedExitCode = exitCode;
+    exitHandler = (code) => exitCode = code;
+    outSink = new StringBuffer();
+    errorSink = new StringBuffer();
+  }
+
+  /// Base teardown.
+  _tearDown() {
+    outSink = savedOutSink;
+    errorSink = savedErrorSink;
+    exitCode = savedExitCode;
+    exitHandler = savedExitHandler;
+  }
+
+  setUp(() => _setUp());
+
+  tearDown(() => _tearDown());
+
+  initializeTestEnvironment();
+
+  group('Bootloader', () {
+    group('plugin processing', () {
+      test('bad format', () {
+        BootLoader loader = new BootLoader();
+        loader.createImage([
+          '--options',
+          path.join(testDirectory, 'data/bad_plugin_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
+        ]);
+        expect(
+            errorSink.toString(),
+            'Plugin configuration skipped: Unrecognized plugin config '
+            'format, expected `YamlMap`, got `YamlList` '
+            '(line 2, column 4)\n');
+      });
+      test('plugin config', () {
+        BootLoader loader = new BootLoader();
+        Image image = loader.createImage([
+          '--options',
+          path.join(testDirectory, 'data/plugin_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
+        ]);
+        var plugins = image.config.plugins;
+        expect(plugins, hasLength(1));
+        expect(plugins.first.name, 'my_plugin1');
+      });
+      group('plugin validation', () {
+        test('requires class name', () {
+          expect(
+              validate(new PluginInfo(
+                  name: 'test_plugin', libraryUri: 'my_package/foo.dart')),
+              isNotNull);
+        });
+        test('requires library URI', () {
+          expect(
+              validate(
+                  new PluginInfo(name: 'test_plugin', className: 'MyPlugin')),
+              isNotNull);
+        });
+        test('check', () {
+          expect(
+              validate(new PluginInfo(
+                  name: 'test_plugin',
+                  className: 'MyPlugin',
+                  libraryUri: 'my_package/foo.dart')),
+              isNull);
+        });
+      });
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index d85b818..244788c 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -12,9 +12,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/plugin/plugin_configuration.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer_cli/src/bootloader.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:path/path.dart' as path;
@@ -351,56 +349,7 @@
 //    });
   });
 
-  group('Bootloader', () {
-    group('plugin processing', () {
-      test('bad format', () {
-        BootLoader loader = new BootLoader();
-        loader.createImage([
-          '--options',
-          path.join(testDirectory, 'data/bad_plugin_options.yaml'),
-          path.join(testDirectory, 'data/test_file.dart')
-        ]);
-        expect(
-            errorSink.toString(),
-            equals('Plugin configuration skipped: Unrecognized plugin config '
-                'format, expected `YamlMap`, got `YamlList` '
-                '(line 2, column 4)\n'));
-      });
-      test('plugin config', () {
-        BootLoader loader = new BootLoader();
-        Image image = loader.createImage([
-          '--options',
-          path.join(testDirectory, 'data/plugin_options.yaml'),
-          path.join(testDirectory, 'data/test_file.dart')
-        ]);
-        var plugins = image.config.plugins;
-        expect(plugins, hasLength(1));
-        expect(plugins.first.name, equals('my_plugin1'));
-      });
-      group('plugin validation', () {
-        test('requires class name', () {
-          expect(
-              validate(new PluginInfo(
-                  name: 'test_plugin', libraryUri: 'my_package/foo.dart')),
-              isNotNull);
-        });
-        test('requires library URI', () {
-          expect(
-              validate(
-                  new PluginInfo(name: 'test_plugin', className: 'MyPlugin')),
-              isNotNull);
-        });
-        test('check', () {
-          expect(
-              validate(new PluginInfo(
-                  name: 'test_plugin',
-                  className: 'MyPlugin',
-                  libraryUri: 'my_package/foo.dart')),
-              isNull);
-        });
-      });
-    });
-  });
+
 }
 
 const emptyOptionsFile = 'data/empty_options.yaml';
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 2c3c9a2..8f81d15 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -435,7 +435,10 @@
     if (packages == null) {
       setupFutures.add(setupPackages(uri));
     }
-    return Future.wait(setupFutures).then((_) => super.analyzeUri(uri));
+    return Future.wait(setupFutures).then((_) {
+      return super.analyzeUri(uri,
+          skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
+    });
   }
 
   Future setupPackages(Uri uri) {
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index f777c0a..70ebabe 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -97,10 +97,18 @@
   static final Selector noSuchMethod_ =
       new Selector.call(Names.noSuchMethod_, CallStructure.ONE_ARG);
 
+  /// The selector for tearing off noSuchMethod.
+  static final Selector noSuchMethodGetter =
+      new Selector.getter(Names.noSuchMethod_);
+
   /// The selector for calling the to-string method on 'Object'.
   static final Selector toString_ =
       new Selector.call(Names.toString_, CallStructure.NO_ARGS);
 
+  /// The selector for tearing off toString.
+  static final Selector toStringGetter =
+      new Selector.getter(Names.toString_);
+
   static final Selector hashCode_ =
       new Selector.getter(const PublicName('hashCode'));
 
@@ -123,8 +131,9 @@
   /// These objects are shared between different runs in batch-mode and must
   /// thus remain in the [Selector.canonicalizedValues] map.
   static final List<Selector> ALL = <Selector>[
-      cancel, current, iterator, moveNext, noSuchMethod_, toString_,
-      hashCode_, compareTo, equals, length, codeUnitAt, index, runtimeType_];
+      cancel, current, iterator, moveNext, noSuchMethod_, noSuchMethodGetter,
+      toString_, toStringGetter, hashCode_, compareTo, equals, length,
+      codeUnitAt, index, runtimeType_];
 }
 
 /// [Uri]s commonly used.
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index ceb9143..53be699 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -962,11 +962,10 @@
       {bool skipLibraryWithPartOfTag: true}) {
     assert(analyzeMain);
     reporter.log('Analyzing $libraryUri ($buildId)');
-    return libraryLoader.loadLibrary(libraryUri).then((LibraryElement library) {
-      var compilationUnit = library.compilationUnit;
-      if (skipLibraryWithPartOfTag && compilationUnit.partTag != null) {
-        return null;
-      }
+    return libraryLoader.loadLibrary(
+        libraryUri, skipFileWithPartOfTag: true).then(
+            (LibraryElement library) {
+      if (library == null) return null;
       fullyEnqueueLibrary(library, enqueuer.resolution);
       emptyQueue(enqueuer.resolution);
       enqueuer.resolution.logSummary(reporter.log);
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index 4a15ac9..c2c819e 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -332,6 +332,16 @@
   apply(left, right) => identical(left, right);
 }
 
+class IfNullOperation implements BinaryOperation {
+  final String name = '??';
+  const IfNullOperation();
+  ConstantValue fold(ConstantValue left, ConstantValue right) {
+    if (left.isNull) return right;
+    return left;
+  }
+  apply(left, right) => left ?? right;
+}
+
 abstract class CodeUnitAtOperation implements BinaryOperation {
   final String name = 'charCodeAt';
   const CodeUnitAtOperation();
@@ -382,6 +392,7 @@
   final greaterEqual = const GreaterEqualOperation();
   final greater = const GreaterOperation();
   final identity = const IdentityOperation();
+  final ifNull = const IfNullOperation();
   final lessEqual = const LessEqualOperation();
   final less = const LessOperation();
   final modulo = const ModuloOperation();
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index d99d795..06c9fad 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -43,6 +43,7 @@
   BinaryOperation get greaterEqual;
   BinaryOperation get greater;
   BinaryOperation get identity;
+  BinaryOperation get ifNull;
   BinaryOperation get lessEqual;
   BinaryOperation get less;
   BinaryOperation get modulo;
@@ -118,6 +119,7 @@
       case BinaryOperatorKind.GT:   return greater;
       case BinaryOperatorKind.GTEQ:  return greaterEqual;
       case BinaryOperatorKind.EQ:  return equal;
+      case BinaryOperatorKind.IF_NULL: return ifNull;
       default:    return null;
     }
   }
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index f1ad90b..02f7b1a 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -804,6 +804,7 @@
     BinaryOperatorKind.GTEQ: 7,
     BinaryOperatorKind.LTEQ: 7,
     BinaryOperatorKind.MOD: 13,
+    BinaryOperatorKind.IF_NULL: 3,
   };
 }
 
@@ -1605,4 +1606,4 @@
   }
 
   String toString() => sb.toString();
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
index e5caa83..422aaa3 100644
--- a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
+++ b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
@@ -1,7 +1,7 @@
 library dart2js.cps_ir.backward_null_check_remover;
 
 import 'cps_ir_nodes.dart';
-import 'optimizers.dart' show Pass;
+import 'optimizers.dart';
 import '../common/names.dart';
 import '../universe/selector.dart';
 import 'type_mask_system.dart';
@@ -31,8 +31,7 @@
 //   bad so changing that should be ok, but changing a field access is not as
 //   clear.
 //
-class BackwardNullCheckRemover extends TrampolineRecursiveVisitor
-                               implements Pass {
+class BackwardNullCheckRemover extends BlockVisitor implements Pass {
   String get passName => 'Backward null-check remover';
 
   final TypeMaskSystem typeSystem;
@@ -41,10 +40,14 @@
   /// a value that is checked in the beginning of that expression.
   Primitive nullCheckedValue;
 
+  /// The [nullCheckedValue] at the entry point of a continuation.
+  final Map<Continuation, Primitive> nullCheckedValueAt =
+      <Continuation, Primitive>{};
+
   BackwardNullCheckRemover(this.typeSystem);
 
   void rewrite(FunctionDefinition node) {
-    visit(node);
+    BlockVisitor.traverseInPostOrder(node, this);
   }
 
   /// Returns a reference to an operand of [prim], where [prim] throws if null
@@ -56,16 +59,15 @@
     if (prim is GetIndex) return prim.object;
     if (prim is SetField) return prim.object;
     if (prim is SetIndex) return prim.object;
-    if (prim is InvokeMethod && !nullSelectors.contains(prim.selector)) {
+    if (prim is InvokeMethod && !selectorsOnNull.contains(prim.selector)) {
       return prim.dartReceiverReference;
     }
+    if (prim is ForeignCode) {
+      return prim.isNullGuardOnNullFirstArgument() ? prim.arguments[0] : null;
+    }
     return null;
   }
 
-  static final List<Selector> nullSelectors = <Selector>[
-      Selectors.equals, Selectors.hashCode_, Selectors.noSuchMethod_,
-      Selectors.runtimeType_];
-
   /// It has been determined that the null check in [prim] made redundant by
   /// [newNullCheck].  Eliminate [prim] if it is not needed any more.
   void tryEliminateRedundantNullCheck(Primitive prim, Primitive newNullCheck) {
@@ -95,37 +97,33 @@
     return prim.isSafeForReordering;
   }
 
-  Expression traverseLetPrim(LetPrim node) {
+  void visitLetPrim(LetPrim node) {
     Primitive prim = node.primitive;
     Primitive receiver = getNullCheckedOperand(prim)?.definition;
     if (receiver != null) {
-      pushAction(() {
-        Primitive successor = nullCheckedValue;
-        if (successor != null && receiver.sameValue(successor)) {
-          tryEliminateRedundantNullCheck(prim, successor);
-        }
-        nullCheckedValue = receiver;
-      });
+      if (nullCheckedValue != null && receiver.sameValue(nullCheckedValue)) {
+        tryEliminateRedundantNullCheck(prim, nullCheckedValue);
+      }
+      nullCheckedValue = receiver;
     } else if (!canMoveAboveNullCheck(prim)) {
-      pushAction(() {
-        nullCheckedValue = null;
-      });
+      nullCheckedValue = null;
     }
-    return node.body;
   }
 
-  Expression traverseContinuation(Continuation cont) {
-    pushAction(() {
+  void visitContinuation(Continuation cont) {
+    if (nullCheckedValue != null) {
+      nullCheckedValueAt[cont] = nullCheckedValue;
       nullCheckedValue = null;
-    });
-    return cont.body;
+    }
   }
 
-  Expression traverseLetHandler(LetHandler node) {
-    push(node.handler);
-    pushAction(() {
-      nullCheckedValue = null;
-    });
-    return node.body;
+  void visitLetHandler(LetHandler node) {
+    nullCheckedValue = null;
+  }
+
+  visitInvokeContinuation(InvokeContinuation node) {
+    if (!node.isRecursive) {
+      nullCheckedValue = nullCheckedValueAt[node.continuation.definition];
+    }
   }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
index 699e755..2db4ac5 100644
--- a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
+++ b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
@@ -158,26 +158,41 @@
 
 /// A method supported natively in the CPS and Tree IRs using the
 /// `ApplyBuiltinMethod` instructions.
-/// 
+///
 /// These methods all operate on a distinguished 'object' argument, and
 /// take zero or more additional arguments.
-/// 
+///
 /// These methods may mutate and depend on the state of the object argument,
 /// but may not depend on or mutate any other state. An exception is thrown
 /// if the object is null, but otherwise they cannot throw or diverge.
 enum BuiltinMethod {
   /// Add an item to a native list.
-  /// 
+  ///
   /// Takes any number of arguments, each argument will be added to the
   /// list on the order given (as per the JS `push` method).
-  /// 
+  ///
   /// Compiles to `object.push(x1, ..., xN)`.
   Push,
 
   /// Remove and return the last item from a native list.
-  /// 
+  ///
   /// Takes no arguments.
-  /// 
+  ///
   /// Compiles to `object.pop()`.
   Pop,
 }
+
+/// True for the built-in operators that may be used in a compound assignment.
+bool isCompoundableOperator(BuiltinOperator operator) {
+  switch(operator) {
+    case BuiltinOperator.NumAdd:
+    case BuiltinOperator.NumSubtract:
+    case BuiltinOperator.NumMultiply:
+    case BuiltinOperator.NumDivide:
+    case BuiltinOperator.NumRemainder:
+    case BuiltinOperator.StringConcatenate:
+      return true;
+    default:
+      return false;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
index a4bd305..7e62fa5 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
@@ -135,8 +135,9 @@
       List<Primitive> arguments,
       [CallingConvention callingConvention = CallingConvention.Normal]) {
     InvokeMethod invoke =
-        new InvokeMethod(receiver, selector, mask, arguments, sourceInformation)
-            ..callingConvention = callingConvention;
+        new InvokeMethod(receiver, selector, mask, arguments,
+                         sourceInformation: sourceInformation,
+                         callingConvention: callingConvention);
     return letPrim(invoke);
   }
 
@@ -188,31 +189,39 @@
 
   /// Branch on [condition].
   ///
-  /// Returns a new fragment for the 'then' branch.
+  /// Returns a new fragment for the 'then' branch, or the 'else' branch
+  /// if [negate] is true.
   ///
-  /// The 'else' branch becomes the new hole.
-  CpsFragment ifTruthy(Primitive condition) {
+  /// The other branch becomes the new hole.
+  CpsFragment branch(Primitive condition,
+                     {bool negate: false,
+                      bool strict: false}) {
     Continuation trueCont = new Continuation(<Parameter>[]);
     Continuation falseCont = new Continuation(<Parameter>[]);
     put(new LetCont.two(trueCont, falseCont,
-            new Branch.loose(condition, trueCont, falseCont)));
-    context = falseCont;
-    return new CpsFragment(sourceInformation, trueCont);
+            new Branch(condition, trueCont, falseCont, strict: strict)));
+    if (negate) {
+      context = trueCont;
+      return new CpsFragment(sourceInformation, falseCont);
+    } else {
+      context = falseCont;
+      return new CpsFragment(sourceInformation, trueCont);
+    }
   }
 
   /// Branch on [condition].
   ///
+  /// Returns a new fragment for the 'then' branch.
+  ///
+  /// The 'else' branch becomes the new hole.
+  CpsFragment ifTruthy(Primitive condition) => branch(condition);
+
+  /// Branch on [condition].
+  ///
   /// Returns a new fragment for the 'else' branch.
   ///
   /// The 'then' branch becomes the new hole.
-  CpsFragment ifFalsy(Primitive condition) {
-    Continuation trueCont = new Continuation(<Parameter>[]);
-    Continuation falseCont = new Continuation(<Parameter>[]);
-    put(new LetCont.two(trueCont, falseCont,
-            new Branch.loose(condition, trueCont, falseCont)));
-    context = trueCont;
-    return new CpsFragment(sourceInformation, falseCont);
-  }
+  CpsFragment ifFalsy(Primitive condition) => branch(condition, negate: true);
 
   /// Create a new empty continuation and bind it here.
   ///
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index 76b2d22..0a80f33 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -4,7 +4,7 @@
 
 library dart2js.ir_builder;
 
-import '../closure.dart' hide ClosureScope;
+import '../closure.dart' as closure;
 import '../common.dart';
 import '../common/names.dart' show
     Names,
@@ -209,7 +209,7 @@
     for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) {
       for (LocalVariableElement variable in boxedOnEntry) {
         assert(builder.isInMutableVariable(variable));
-        ir.Primitive value = builder.buildLocalVariableGet(variable);
+        ir.Primitive value = builder.buildLocalGet(variable);
         builder.environment.update(variable, value);
       }
     }
@@ -653,10 +653,10 @@
     return primitive;
   }
 
-  ir.Primitive _buildInvokeStatic(Element element,
-                                  Selector selector,
-                                  List<ir.Primitive> arguments,
-                                  SourceInformation sourceInformation) {
+  ir.Primitive buildInvokeStatic(Element element,
+                                 Selector selector,
+                                 List<ir.Primitive> arguments,
+                                 SourceInformation sourceInformation) {
     assert(!element.isLocal);
     assert(!element.isInstanceMember);
     assert(isOpen);
@@ -681,7 +681,8 @@
                                    SourceInformation sourceInformation) {
     assert(isOpen);
     return addPrimitive(new ir.InvokeMethod(
-        receiver, selector, mask, arguments, sourceInformation));
+        receiver, selector, mask, arguments,
+        sourceInformation: sourceInformation));
   }
 
   ir.Primitive _buildInvokeCall(ir.Primitive target,
@@ -696,18 +697,15 @@
 
   ir.Primitive buildStaticNoSuchMethod(Selector selector,
                                        List<ir.Primitive> arguments) {
-    Element thrower = program.throwNoSuchMethod;
     ir.Primitive receiver = buildStringConstant('');
     ir.Primitive name = buildStringConstant(selector.name);
     ir.Primitive argumentList = buildListLiteral(null, arguments);
     ir.Primitive expectedArgumentNames = buildNullConstant();
     return buildStaticFunctionInvocation(
-        thrower,
-        new CallStructure.unnamed(4),
-        [receiver, name, argumentList, expectedArgumentNames]);
+        program.throwNoSuchMethod,
+        <ir.Primitive>[receiver, name, argumentList, expectedArgumentNames]);
   }
 
-
   /// Create a [ir.Constant] from [value] and add it to the CPS term.
   ir.Constant buildConstant(ConstantValue value,
                             {SourceInformation sourceInformation}) {
@@ -757,24 +755,6 @@
         allocationSiteType: allocationSiteType));
   }
 
-  /// Creates a non-constant map literal of the provided [type] and with the
-  /// entries build from the [keys] and [values] using [build].
-  ir.Primitive buildMapLiteral(InterfaceType type,
-                               Iterable keys,
-                               Iterable values,
-                               BuildFunction build) {
-    assert(isOpen);
-    List<ir.LiteralMapEntry> entries = <ir.LiteralMapEntry>[];
-    Iterator key = keys.iterator;
-    Iterator value = values.iterator;
-    while (key.moveNext() && value.moveNext()) {
-      entries.add(new ir.LiteralMapEntry(
-          build(key.current), build(value.current)));
-    }
-    assert(!key.moveNext() && !value.moveNext());
-    return addPrimitive(new ir.LiteralMap(type, entries));
-  }
-
   /// Creates a conditional expression with the provided [condition] where the
   /// then and else expression are created through the [buildThenExpression]
   /// and [buildElseExpression] functions, respectively.
@@ -985,32 +965,6 @@
     return value;
   }
 
-  /// Create a read access of the [local] variable or parameter.
-  ir.Primitive buildLocalVariableGet(LocalElement local) {
-    // TODO(johnniwinther): Separate function access from variable access.
-    return _buildLocalGet(local);
-  }
-
-  /// Create a read access of the local [function], i.e. closurization of
-  /// [function].
-  ir.Primitive buildLocalFunctionGet(LocalFunctionElement function) {
-    // TODO(johnniwinther): Separate function access from variable access.
-    return _buildLocalGet(function);
-  }
-
-  /// Create an invocation of the the [local] variable or parameter where
-  /// argument structure is defined by [callStructure] and the argument values
-  /// are defined by [arguments].
-  ir.Primitive buildLocalVariableInvocation(
-      LocalVariableElement local,
-      CallStructure callStructure,
-      List<ir.Primitive> arguments,
-      {SourceInformation callSourceInformation}) {
-    return buildCallInvocation(
-        buildLocalVariableGet(local), callStructure, arguments,
-        sourceInformation: callSourceInformation);
-  }
-
   /// Create an invocation of the local [function] where argument structure is
   /// defined by [callStructure] and the argument values are defined by
   /// [arguments].
@@ -1021,52 +975,30 @@
       SourceInformation sourceInformation) {
     // TODO(johnniwinther): Maybe this should have its own ir node.
     return buildCallInvocation(
-        buildLocalFunctionGet(function), callStructure, arguments,
+        buildLocalGet(function), callStructure, arguments,
         sourceInformation: sourceInformation);
   }
 
-  /// Create a static invocation of [function] where argument structure is
-  /// defined by [callStructure] and the argument values are defined by
-  /// [arguments].
+  /// Create a static invocation of [function].
+  ///
+  /// The arguments are not named and their values are defined by [arguments].
   ir.Primitive buildStaticFunctionInvocation(
       MethodElement function,
-      CallStructure callStructure,
       List<ir.Primitive> arguments,
       {SourceInformation sourceInformation}) {
-    Selector selector =
-        new Selector(SelectorKind.CALL, function.memberName, callStructure);
-    return _buildInvokeStatic(
-        function, selector, arguments, sourceInformation);
-  }
-
-  /// Create a read access of the static [field].
-  ir.Primitive buildStaticFieldGet(FieldElement field,
-                                   SourceInformation sourceInformation) {
-    return addPrimitive(new ir.GetStatic(field, sourceInformation));
-  }
-
-  /// Create a read access of a static [field] that might not have been
-  /// initialized yet.
-  ir.Primitive buildStaticFieldLazyGet(FieldElement field,
-                                       SourceInformation sourceInformation) {
-    return addPrimitive(new ir.GetLazyStatic(field, sourceInformation));
+    Selector selector = new Selector.call(
+        function.memberName, new CallStructure(arguments.length));
+    return buildInvokeStatic(function, selector, arguments, sourceInformation);
   }
 
   /// Create a getter invocation of the static [getter].
   ir.Primitive buildStaticGetterGet(MethodElement getter,
                                     SourceInformation sourceInformation) {
     Selector selector = new Selector.getter(getter.memberName);
-    return _buildInvokeStatic(
+    return buildInvokeStatic(
         getter, selector, const <ir.Primitive>[], sourceInformation);
   }
 
-  /// Create a read access of the static [function], i.e. a closurization of
-  /// [function].
-  ir.Primitive buildStaticFunctionGet(MethodElement function,
-                                      {SourceInformation sourceInformation}) {
-    return addPrimitive(new ir.GetStatic(function, sourceInformation));
-  }
-
   /// Create a write access to the static [field] with the [value].
   ir.Primitive buildStaticFieldSet(FieldElement field,
                                    ir.Primitive value,
@@ -1080,7 +1012,7 @@
                                     ir.Primitive value,
                                     {SourceInformation sourceInformation}) {
     Selector selector = new Selector.setter(setter.memberName);
-    _buildInvokeStatic(
+    buildInvokeStatic(
         setter, selector, <ir.Primitive>[value], sourceInformation);
     return value;
   }
@@ -1093,13 +1025,10 @@
       Selector selector,
       List<ir.Primitive> arguments) {
     // TODO(johnniwinther): This should have its own ir node.
-    return _buildInvokeStatic(element, selector, arguments, null);
+    return buildInvokeStatic(element, selector, arguments, null);
   }
 
-  /// Concatenate string values.
-  ///
-  /// The arguments must be strings; usually a call to [buildStringify] is
-  /// needed to ensure the proper conversion takes places.
+  /// Concatenate string values.  The arguments must be strings.
   ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments,
                                         {SourceInformation sourceInformation}) {
     assert(isOpen);
@@ -1433,8 +1362,6 @@
             Selectors.current,
             currentMask,
             emptyArguments));
-    // TODO(sra): Does this cover all cases? The general setter case include
-    // super.
     // TODO(johnniwinther): Extract this as a provided strategy.
     if (Elements.isLocal(variableElement)) {
       bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
@@ -1452,7 +1379,8 @@
       }
     } else if (Elements.isStaticOrTopLevel(variableElement)) {
       if (variableElement.isField) {
-        bodyBuilder.buildStaticFieldSet(variableElement, currentValue);
+        bodyBuilder.addPrimitive(
+            new ir.SetStatic(variableElement, currentValue));
       } else {
         bodyBuilder.buildStaticSetterSet(variableElement, currentValue);
       }
@@ -1698,7 +1626,7 @@
         if (caseInfo == cases.last && defaultCase == null) {
           thenBuilder.jumpTo(join);
         } else {
-          ir.Primitive exception = thenBuilder._buildInvokeStatic(
+          ir.Primitive exception = thenBuilder.buildInvokeStatic(
               error,
               new Selector.fromElement(error),
               <ir.Primitive>[],
@@ -1766,7 +1694,7 @@
         new Map<Local, ir.MutableVariable>.from(mutableVariables);
     for (LocalVariableElement variable in variables.boxedOnEntry) {
       assert(!tryCatchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable);
+      ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
       tryCatchBuilder.makeMutableVariable(variable);
       tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
     }
@@ -1784,7 +1712,7 @@
     IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
     for (LocalVariableElement variable in variables.boxedOnEntry) {
       assert(catchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = catchBuilder.buildLocalVariableGet(variable);
+      ir.Primitive value = catchBuilder.buildLocalGet(variable);
       // After this point, the variables that were boxed on entry to the try
       // are no longer treated as mutable.
       catchBuilder.removeMutableVariable(variable);
@@ -2072,16 +2000,6 @@
     jumpTo(state.returnCollector, value, sourceInformation);
   }
 
-  /// Build a call to the closure conversion helper for the [Function] typed
-  /// value in [value].
-  ir.Primitive _convertDartClosure(ir.Primitive value, FunctionType type) {
-    ir.Constant arity = buildIntegerConstant(type.computeArity());
-    return buildStaticFunctionInvocation(
-        program.closureConverter,
-        CallStructure.TWO_ARGS,
-        <ir.Primitive>[value, arity]);
-  }
-
   /// Generate the body for a native function [function] that is annotated with
   /// an implementation in JavaScript (provided as string in [javaScriptCode]).
   void buildNativeFunctionBody(FunctionElement function,
@@ -2123,7 +2041,9 @@
       if (type is FunctionType) {
         // The parameter type is a function type either directly or through
         // typedef(s).
-        input = _convertDartClosure(input, type);
+        ir.Constant arity = buildIntegerConstant(type.computeArity());
+        input = buildStaticFunctionInvocation(
+            program.closureConverter, <ir.Primitive>[input, arity]);
       }
       arguments.add(input);
       argumentTemplates.add('#');
@@ -2466,24 +2386,24 @@
 
   /// Add [functionElement] to the environment with provided [definition].
   void declareLocalFunction(LocalFunctionElement functionElement,
-                            ClosureClassElement classElement,
+                            closure.ClosureClassElement classElement,
                             SourceInformation sourceInformation) {
     ir.Primitive closure =
          buildFunctionExpression(classElement, sourceInformation);
     declareLocalVariable(functionElement, initialValue: closure);
   }
 
-  ir.Primitive buildFunctionExpression(ClosureClassElement classElement,
+  ir.Primitive buildFunctionExpression(closure.ClosureClassElement classElement,
                                        SourceInformation sourceInformation) {
     List<ir.Primitive> arguments = <ir.Primitive>[];
-    for (ClosureFieldElement field in classElement.closureFields) {
+    for (closure.ClosureFieldElement field in classElement.closureFields) {
       // Captured 'this' and type variables are not always available as locals
       // in the environment, so treat those specially.
       ir.Primitive value;
-      if (field.local is ThisLocal) {
+      if (field.local is closure.ThisLocal) {
         value = buildThis();
-      } else if (field.local is TypeVariableLocal) {
-        TypeVariableLocal variable = field.local;
+      } else if (field.local is closure.TypeVariableLocal) {
+        closure.TypeVariableLocal variable = field.local;
         value = buildTypeVariableAccess(variable.typeVariable);
       } else {
         value = environment.lookup(field.local);
@@ -2494,8 +2414,8 @@
         classElement, arguments, const <ir.Primitive>[], sourceInformation));
   }
 
-  /// Create a read access of [local] variable or parameter.
-  ir.Primitive _buildLocalGet(LocalElement local) {
+  /// Create a read access of [local] function, variable, or parameter.
+  ir.Primitive buildLocalGet(LocalElement local) {
     assert(isOpen);
     ClosureLocation location = state.boxedVariables[local];
     if (location != null) {
@@ -2600,17 +2520,6 @@
     return value;
   }
 
-  ir.Primitive buildInvokeDirectly(MethodElement target,
-                                   ir.Primitive receiver,
-                                   List<ir.Primitive> arguments,
-                                   {SourceInformation sourceInformation}) {
-    assert(isOpen);
-    Selector selector =
-        new Selector.call(target.memberName, new CallStructure(arguments.length));
-    return addPrimitive(new ir.InvokeMethodDirectly(
-        receiver, target, selector, arguments, sourceInformation));
-  }
-
   /// Loads parameters to a constructor body into the environment.
   ///
   /// The header for a constructor body differs from other functions in that
@@ -2688,7 +2597,7 @@
     // If the local exists in the environment, use that.
     // This is put here when we are inside a constructor or field initializer,
     // (or possibly a closure inside one of these).
-    Local local = new TypeVariableLocal(variable, state.currentElement);
+    Local local = new closure.TypeVariableLocal(variable, state.currentElement);
     if (environment.contains(local)) {
       return environment.lookup(local);
     }
@@ -2704,7 +2613,7 @@
   /// with the value of [binding].
   void declareTypeVariable(TypeVariableType variable, DartType binding) {
     environment.extend(
-        new TypeVariableLocal(variable, state.currentElement),
+        new closure.TypeVariableLocal(variable, state.currentElement),
         buildTypeExpression(binding));
   }
 
@@ -2752,12 +2661,10 @@
     type = program.unaliasType(type);
 
     if (type.isMalformed) {
-      FunctionElement helper = program.throwTypeErrorHelper;
       ErroneousElement element = type.element;
       ir.Primitive message = buildStringConstant(element.message);
       return buildStaticFunctionInvocation(
-          helper,
-          CallStructure.ONE_ARG,
+          program.throwTypeErrorHelper,
           <ir.Primitive>[message]);
     }
 
@@ -2823,26 +2730,6 @@
     return buildIdentical(value, buildNullConstant(),
         sourceInformation: sourceInformation);
   }
-
-  /// Convert the given value to a string.
-  ir.Primitive buildStringify(ir.Primitive value) {
-    return buildStaticFunctionInvocation(
-        program.stringifyFunction,
-        new CallStructure.unnamed(1),
-        <ir.Primitive>[value]);
-  }
-
-  ir.Primitive buildAwait(ir.Primitive value) {
-    return addPrimitive(new ir.Await(value));
-  }
-
-  void buildYield(ir.Primitive value, bool hasStar) {
-    addPrimitive(new ir.Yield(value, hasStar));
-  }
-
-  ir.Primitive buildRefinement(ir.Primitive value, TypeMask type) {
-    return addPrimitive(new ir.Refinement(value, type));
-  }
 }
 
 /// Location of a variable relative to a given closure.
@@ -2851,7 +2738,7 @@
   /// The location of [box] can be obtained separately from an
   /// enclosing [ClosureEnvironment] or [ClosureScope].
   /// If `null`, then the location is [field] on the enclosing function object.
-  final BoxLocal box;
+  final closure.BoxLocal box;
 
   /// The field in which the variable is stored.
   final Entity field;
@@ -2859,6 +2746,21 @@
   bool get isBox => box != null;
 
   ClosureLocation(this.box, this.field);
+
+  /// Converts a map containing closure.dart's [CapturedVariable]s into one
+  /// containing [ClosureLocation]s.
+  ///
+  /// There is a 1:1 corresponce between these; we do this because the
+  /// IR builder should not depend on synthetic elements.
+  static Map<Local, ClosureLocation> mapFrom(
+      Map<Local, closure.CapturedVariable> map) {
+    Map result = {};
+    map.forEach((Local k, closure.CapturedVariable v) {
+      closure.BoxLocal box = v is closure.BoxFieldElement ? v.box : null;
+      result[k] = new ClosureLocation(box, v);
+    });
+    return result;
+  }
 }
 
 /// Introduces a new box and binds local variables to this box.
@@ -2868,7 +2770,7 @@
 /// [ClosureScope] when a given scope has no boxed variables.
 class ClosureScope {
   /// This box is now in scope and [capturedVariables] may use it.
-  final BoxLocal box;
+  final closure.BoxLocal box;
 
   /// Maps [LocalElement]s to their location.
   final Map<Local, ClosureLocation> capturedVariables;
@@ -2877,7 +2779,14 @@
   /// of boxed variables that are declared in the initializer.
   final List<VariableElement> boxedLoopVariables;
 
-  ClosureScope(this.box, this.capturedVariables, this.boxedLoopVariables);
+  factory ClosureScope(closure.ClosureScope scope) {
+    return scope == null ? null : new ClosureScope._internal(scope);
+  }
+
+  ClosureScope._internal(closure.ClosureScope scope)
+      : box = scope.boxElement,
+        capturedVariables = ClosureLocation.mapFrom(scope.capturedVariables),
+        boxedLoopVariables = scope.boxedLoopVariables;
 }
 
 /// Environment passed when building a nested function, describing how
@@ -2889,12 +2798,21 @@
 
   /// If non-null, [thisLocal] has an entry in [freeVariables] describing where
   /// to find the captured value of `this`.
-  final ThisLocal thisLocal;
+  final closure.ThisLocal thisLocal;
 
   /// Maps [LocalElement]s, [BoxLocal]s and [ThisLocal] to their location.
   final Map<Local, ClosureLocation> freeVariables;
 
-  ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables);
+  factory ClosureEnvironment(closure.ClosureClassMap closureClassMap) {
+    if (closureClassMap.closureElement == null) return null;
+    return new ClosureEnvironment._internal(closureClassMap);
+  }
+
+  ClosureEnvironment._internal(closure.ClosureClassMap closureClassMap)
+      : selfReference = closureClassMap.closureElement,
+        thisLocal = closureClassMap.thisLocal,
+        freeVariables =
+            ClosureLocation.mapFrom(closureClassMap.freeVariableMap);
 }
 
 class TryStatementInfo {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index ee7a870..5c55f63 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -4,8 +4,7 @@
 
 library dart2js.ir_builder_task;
 
-import '../closure.dart' as closurelib;
-import '../closure.dart' hide ClosureScope;
+import '../closure.dart' as closure;
 import '../common.dart';
 import '../common/names.dart' show
     Names,
@@ -91,7 +90,7 @@
             sourceInformationStrategy.createBuilderForContext(element);
 
         IrBuilderVisitor builder =
-            new JsIrBuilderVisitor(
+            new IrBuilderVisitor(
                 elementsMapping, compiler, sourceInformationBuilder,
                 typeMaskSystem);
         ir.FunctionDefinition irNode = builder.buildExecutable(element);
@@ -115,7 +114,7 @@
 /// For expressions, the primitive holding the resulting value is returned.
 /// For statements, `null` is returned.
 // TODO(johnniwinther): Implement [SemanticDeclVisitor].
-abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
+class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
     with IrBuilderMixin<ast.Node>,
          SemanticSendResolvedMixin<ir.Primitive, dynamic>,
          ErrorBulkMixin<ir.Primitive, dynamic>,
@@ -165,26 +164,638 @@
                    this.sourceInformationBuilder,
                    this.typeMaskSystem);
 
+  JavaScriptBackend get backend => compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   DiagnosticReporter get reporter => compiler.reporter;
 
   String bailoutMessage = null;
 
+  ir.Primitive visit(ast.Node node) => node.accept(this);
+
   @override
   ir.Primitive apply(ast.Node node, _) => node.accept(this);
 
-  @override
   SemanticSendVisitor get sendVisitor => this;
 
-  /**
-   * Builds the [ir.FunctionDefinition] for an executable element. In case the
-   * function uses features that cannot be expressed in the IR, this element
-   * returns `null`.
-   */
-  ir.FunctionDefinition buildExecutable(ExecutableElement element);
+  /// Result of closure conversion for the current body of code.
+  ///
+  /// Will be initialized upon entering the body of a function.
+  /// It is computed by the [ClosureTranslator].
+  closure.ClosureClassMap closureClassMap;
 
-  ClosureClassMap get closureClassMap;
-  ClosureScope getClosureScopeForNode(ast.Node node);
-  ClosureEnvironment getClosureEnvironment();
+  /// If [node] has declarations for variables that should be boxed,
+  /// returns a [ClosureScope] naming a box to create, and enumerating the
+  /// variables that should be stored in the box.
+  ///
+  /// Also see [ClosureScope].
+  ClosureScope getClosureScopeForNode(ast.Node node) {
+    // We translate a ClosureScope from closure.dart into IR builder's variant
+    // because the IR builder should not depend on the synthetic elements
+    // created in closure.dart.
+    return new ClosureScope(closureClassMap.capturingScopes[node]);
+  }
+
+  /// Returns the [ClosureScope] for any function, possibly different from the
+  /// one currently being built.
+  ClosureScope getClosureScopeForFunction(FunctionElement function) {
+    closure.ClosureClassMap map =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            function,
+            function.node,
+            elements);
+    return new ClosureScope(map.capturingScopes[function.node]);
+  }
+
+  /// If the current function is a nested function with free variables (or a
+  /// captured reference to `this`), returns a [ClosureEnvironment]
+  /// indicating how to access these.
+  ClosureEnvironment getClosureEnvironment() {
+    return new ClosureEnvironment(closureClassMap);
+  }
+
+  IrBuilder getBuilderFor(Element element) {
+    return new IrBuilder(
+        new GlobalProgramInformation(compiler),
+        backend.constants,
+        element);
+  }
+
+  /// Builds the [ir.FunctionDefinition] for an executable element. In case the
+  /// function uses features that cannot be expressed in the IR, this element
+  /// returns `null`.
+  ir.FunctionDefinition buildExecutable(ExecutableElement element) {
+    return nullIfGiveup(() {
+      ir.FunctionDefinition root;
+      switch (element.kind) {
+        case ElementKind.GENERATIVE_CONSTRUCTOR:
+          root = buildConstructor(element);
+          break;
+
+        case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
+          root = buildConstructorBody(element);
+          break;
+
+        case ElementKind.FACTORY_CONSTRUCTOR:
+        case ElementKind.FUNCTION:
+        case ElementKind.GETTER:
+        case ElementKind.SETTER:
+          root = buildFunction(element);
+          break;
+
+        case ElementKind.FIELD:
+          if (Elements.isStaticOrTopLevel(element)) {
+            root = buildStaticFieldInitializer(element);
+          } else {
+            // Instance field initializers are inlined in the constructor,
+            // so we shouldn't need to build anything here.
+            // TODO(asgerf): But what should we return?
+            return null;
+          }
+          break;
+
+        default:
+          reporter.internalError(element, "Unexpected element type $element");
+      }
+      return root;
+    });
+  }
+
+  /// Loads the type variables for all super classes of [superClass] into the
+  /// IR builder's environment with their corresponding values.
+  ///
+  /// The type variables for [currentClass] must already be in the IR builder's
+  /// environment.
+  ///
+  /// Type variables are stored as [TypeVariableLocal] in the environment.
+  ///
+  /// This ensures that access to type variables mentioned inside the
+  /// constructors and initializers will happen through the local environment
+  /// instead of using 'this'.
+  void loadTypeVariablesForSuperClasses(ClassElement currentClass) {
+    if (currentClass.isObject) return;
+    loadTypeVariablesForType(currentClass.supertype);
+    if (currentClass is MixinApplicationElement) {
+      loadTypeVariablesForType(currentClass.mixinType);
+    }
+  }
+
+  /// Loads all type variables for [type] and all of its super classes into
+  /// the environment. All type variables mentioned in [type] must already
+  /// be in the environment.
+  void loadTypeVariablesForType(InterfaceType type) {
+    ClassElement clazz = type.element;
+    assert(clazz.typeVariables.length == type.typeArguments.length);
+    for (int i = 0; i < clazz.typeVariables.length; ++i) {
+      irBuilder.declareTypeVariable(clazz.typeVariables[i],
+          type.typeArguments[i]);
+    }
+    loadTypeVariablesForSuperClasses(clazz);
+  }
+
+  /// Returns the constructor body associated with the given constructor or
+  /// creates a new constructor body, if none can be found.
+  ///
+  /// Returns `null` if the constructor does not have a body.
+  ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
+    // TODO(asgerf): This is largely inherited from the SSA builder.
+    // The ConstructorBodyElement has an invalid function signature, but we
+    // cannot add a BoxLocal as parameter, because BoxLocal is not an element.
+    // Instead of forging ParameterElements to forge a FunctionSignature, we
+    // need a way to create backend methods without creating more fake elements.
+    assert(constructor.isGenerativeConstructor);
+    assert(constructor.isImplementation);
+    if (constructor.isSynthesized) return null;
+    ast.FunctionExpression node = constructor.node;
+    // If we know the body doesn't have any code, we don't generate it.
+    if (!node.hasBody()) return null;
+    if (node.hasEmptyBody()) return null;
+    ClassElement classElement = constructor.enclosingClass;
+    ConstructorBodyElement bodyElement;
+    classElement.forEachBackendMember((Element backendMember) {
+      if (backendMember.isGenerativeConstructorBody) {
+        ConstructorBodyElement body = backendMember;
+        if (body.constructor == constructor) {
+          bodyElement = backendMember;
+        }
+      }
+    });
+    if (bodyElement == null) {
+      bodyElement = new ConstructorBodyElementX(constructor);
+      classElement.addBackendMember(bodyElement);
+
+      if (constructor.isPatch) {
+        // Create origin body element for patched constructors.
+        ConstructorBodyElementX patch = bodyElement;
+        ConstructorBodyElementX origin =
+        new ConstructorBodyElementX(constructor.origin);
+        origin.applyPatch(patch);
+        classElement.origin.addBackendMember(bodyElement.origin);
+      }
+    }
+    assert(bodyElement.isGenerativeConstructorBody);
+    return bodyElement;
+  }
+
+  /// The list of parameters to send from the generative constructor
+  /// to the generative constructor body.
+  ///
+  /// Boxed parameters are not in the list, instead, a [BoxLocal] is passed
+  /// containing the boxed parameters.
+  ///
+  /// For example, given the following constructor,
+  ///
+  ///     Foo(x, y) : field = (() => ++x) { print(x + y) }
+  ///
+  /// the argument `x` would be replaced by a [BoxLocal]:
+  ///
+  ///     Foo_body(box0, y) { print(box0.x + y) }
+  ///
+  List<Local> getConstructorBodyParameters(ConstructorBodyElement body) {
+    List<Local> parameters = <Local>[];
+    ClosureScope scope = getClosureScopeForFunction(body.constructor);
+    if (scope != null) {
+      parameters.add(scope.box);
+    }
+    body.functionSignature.orderedForEachParameter((ParameterElement param) {
+      if (scope != null && scope.capturedVariables.containsKey(param)) {
+        // Do not pass this parameter; the box will carry its value.
+      } else {
+        parameters.add(param);
+      }
+    });
+    return parameters;
+  }
+
+  /// Builds the IR for a given constructor.
+  ///
+  /// 1. Computes the type held in all own or "inherited" type variables.
+  /// 2. Evaluates all own or inherited field initializers.
+  /// 3. Creates the object and assigns its fields and runtime type.
+  /// 4. Calls constructor body and super constructor bodies.
+  /// 5. Returns the created object.
+  ir.FunctionDefinition buildConstructor(ConstructorElement constructor) {
+    // TODO(asgerf): Optimization: If constructor is redirecting, then just
+    //               evaluate arguments and call the target constructor.
+    constructor = constructor.implementation;
+    ClassElement classElement = constructor.enclosingClass.implementation;
+
+    IrBuilder builder = getBuilderFor(constructor);
+
+    final bool requiresTypeInformation =
+    builder.program.requiresRuntimeTypesFor(classElement);
+
+    return withBuilder(builder, () {
+      // Setup parameters and create a box if anything is captured.
+      List<Local> parameters = <Local>[];
+      constructor.functionSignature.orderedForEachParameter(
+          (ParameterElement p) => parameters.add(p));
+
+      int firstTypeArgumentParameterIndex;
+
+      // If instances of the class may need runtime type information, we add a
+      // synthetic parameter for each type parameter.
+      if (requiresTypeInformation) {
+        firstTypeArgumentParameterIndex = parameters.length;
+        classElement.typeVariables.forEach((TypeVariableType variable) {
+          parameters.add(new closure.TypeVariableLocal(variable, constructor));
+        });
+      } else {
+        classElement.typeVariables.forEach((TypeVariableType variable) {
+          irBuilder.declareTypeVariable(variable, const DynamicType());
+        });
+      }
+
+      // Create IR parameters and setup the environment.
+      List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters,
+          closureScope: getClosureScopeForFunction(constructor));
+
+      // Create a list of the values of all type argument parameters, if any.
+      List<ir.Primitive> typeInformation;
+      if (requiresTypeInformation) {
+        typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex);
+      } else {
+        typeInformation = const <ir.Primitive>[];
+      }
+
+      // -- Load values for type variables declared on super classes --
+      // Field initializers for super classes can reference these, so they
+      // must be available before evaluating field initializers.
+      // This could be interleaved with field initialization, but we choose do
+      // get it out of the way here to avoid complications with mixins.
+      loadTypeVariablesForSuperClasses(classElement);
+
+      /// Maps each field from this class or a superclass to its initial value.
+      Map<FieldElement, ir.Primitive> fieldValues =
+      <FieldElement, ir.Primitive>{};
+
+      // -- Evaluate field initializers ---
+      // Evaluate field initializers in constructor and super constructors.
+      List<ConstructorElement> constructorList = <ConstructorElement>[];
+      evaluateConstructorFieldInitializers(
+          constructor, constructorList, fieldValues);
+
+      // All parameters in all constructors are now bound in the environment.
+      // BoxLocals for captured parameters are also in the environment.
+      // The initial value of all fields are now bound in [fieldValues].
+
+      // --- Create the object ---
+      // Get the initial field values in the canonical order.
+      List<ir.Primitive> instanceArguments = <ir.Primitive>[];
+      classElement.forEachInstanceField((ClassElement c, FieldElement field) {
+        ir.Primitive value = fieldValues[field];
+        if (value != null) {
+          instanceArguments.add(value);
+        } else {
+          assert(backend.isNativeOrExtendsNative(c));
+          // Native fields are initialized elsewhere.
+        }
+      }, includeSuperAndInjectedMembers: true);
+
+      ir.Primitive instance = new ir.CreateInstance(
+          classElement,
+          instanceArguments,
+          typeInformation,
+          constructor.hasNode
+              ? sourceInformationBuilder.buildCreate(constructor.node)
+          // TODO(johnniwinther): Provide source information for creation
+          // through synthetic constructors.
+              : null);
+      irBuilder.add(new ir.LetPrim(instance));
+
+      // --- Call constructor bodies ---
+      for (ConstructorElement target in constructorList) {
+        ConstructorBodyElement bodyElement = getConstructorBody(target);
+        if (bodyElement == null) continue; // Skip if constructor has no body.
+        List<ir.Primitive> bodyArguments = <ir.Primitive>[];
+        for (Local param in getConstructorBodyParameters(bodyElement)) {
+          bodyArguments.add(irBuilder.environment.lookup(param));
+        }
+        Selector selector = new Selector.call(target.memberName,
+            new CallStructure(bodyArguments.length));
+        irBuilder.addPrimitive(new ir.InvokeMethodDirectly(
+            instance, bodyElement, selector, bodyArguments, null));
+      }
+
+      // --- step 4: return the created object ----
+      irBuilder.buildReturn(
+          value: instance,
+          sourceInformation:
+          sourceInformationBuilder.buildImplicitReturn(constructor));
+
+      return irBuilder.makeFunctionDefinition();
+    });
+  }
+
+  /// Make a visitor suitable for translating ASTs taken from [context].
+  ///
+  /// Every visitor can only be applied to nodes in one context, because
+  /// the [elements] field is specific to that context.
+  IrBuilderVisitor makeVisitorForContext(AstElement context) {
+    return new IrBuilderVisitor(
+        context.resolvedAst.elements,
+        compiler,
+        sourceInformationBuilder.forContext(context),
+        typeMaskSystem);
+  }
+
+  /// Builds the IR for an [expression] taken from a different [context].
+  ///
+  /// Such expressions need to be compiled with a different [sourceFile] and
+  /// [elements] mapping.
+  ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
+    IrBuilderVisitor visitor = makeVisitorForContext(context);
+    return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
+  }
+
+  /// Evaluate the implicit super call in the given mixin constructor.
+  void forwardSynthesizedMixinConstructor(
+      ConstructorElement constructor,
+      List<ConstructorElement> supers,
+      Map<FieldElement, ir.Primitive> fieldValues) {
+    assert(constructor.enclosingClass.implementation.isMixinApplication);
+    assert(constructor.isSynthesized);
+    ConstructorElement target =
+        constructor.definingConstructor.implementation;
+    // The resolver gives us the exact same FunctionSignature for the two
+    // constructors. The parameters for the synthesized constructor
+    // are already in the environment, so the target constructor's parameters
+    // are also in the environment since their elements are the same.
+    assert(constructor.functionSignature == target.functionSignature);
+    IrBuilderVisitor visitor = makeVisitorForContext(target);
+    visitor.withBuilder(irBuilder, () {
+      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+    });
+  }
+
+  /// In preparation of inlining (part of) [target], the [arguments] are moved
+  /// into the environment bindings for the corresponding parameters.
+  ///
+  /// Defaults for optional arguments are evaluated in order to ensure
+  /// all parameters are available in the environment.
+  void loadArguments(ConstructorElement target,
+      CallStructure call,
+      List<ir.Primitive> arguments) {
+    assert(target.isImplementation);
+    assert(target == elements.analyzedElement);
+    FunctionSignature signature = target.functionSignature;
+
+    // Establish a scope in case parameters are captured.
+    ClosureScope scope = getClosureScopeForFunction(target);
+    irBuilder.enterScope(scope);
+
+    // Load required parameters
+    int index = 0;
+    signature.forEachRequiredParameter((ParameterElement param) {
+      irBuilder.declareLocalVariable(param, initialValue: arguments[index]);
+      index++;
+    });
+
+    // Load optional parameters, evaluating default values for omitted ones.
+    signature.forEachOptionalParameter((ParameterElement param) {
+      ir.Primitive value;
+      // Load argument if provided.
+      if (signature.optionalParametersAreNamed) {
+        int nameIndex = call.namedArguments.indexOf(param.name);
+        if (nameIndex != -1) {
+          int translatedIndex = call.positionalArgumentCount + nameIndex;
+          value = arguments[translatedIndex];
+        }
+      } else if (index < arguments.length) {
+        value = arguments[index];
+      }
+      // Load default if argument was not provided.
+      if (value == null) {
+        if (param.initializer != null) {
+          value = visit(param.initializer);
+        } else {
+          value = irBuilder.buildNullConstant();
+        }
+      }
+      irBuilder.declareLocalVariable(param, initialValue: value);
+      index++;
+    });
+  }
+
+  /// Evaluates a call to the given constructor from an initializer list.
+  ///
+  /// Calls [loadArguments] and [evaluateConstructorFieldInitializers] in a
+  /// visitor that has the proper [TreeElements] mapping.
+  void evaluateConstructorCallFromInitializer(
+      ConstructorElement target,
+      CallStructure call,
+      List<ir.Primitive> arguments,
+      List<ConstructorElement> supers,
+      Map<FieldElement, ir.Primitive> fieldValues) {
+    IrBuilderVisitor visitor = makeVisitorForContext(target);
+    visitor.withBuilder(irBuilder, () {
+      visitor.loadArguments(target, call, arguments);
+      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+    });
+  }
+
+  /// Evaluates all field initializers on [constructor] and all constructors
+  /// invoked through `this()` or `super()` ("superconstructors").
+  ///
+  /// The resulting field values will be available in [fieldValues]. The values
+  /// are not stored in any fields.
+  ///
+  /// This procedure assumes that the parameters to [constructor] are available
+  /// in the IR builder's environment.
+  ///
+  /// The parameters to superconstructors are, however, assumed *not* to be in
+  /// the environment, but will be put there by this procedure.
+  ///
+  /// All constructors will be added to [supers], with superconstructors first.
+  void evaluateConstructorFieldInitializers(
+      ConstructorElement constructor,
+      List<ConstructorElement> supers,
+      Map<FieldElement, ir.Primitive> fieldValues) {
+    assert(constructor.isImplementation);
+    assert(constructor == elements.analyzedElement);
+    ClassElement enclosingClass = constructor.enclosingClass.implementation;
+    // Evaluate declaration-site field initializers, unless this constructor
+    // redirects to another using a `this()` initializer. In that case, these
+    // will be initialized by the effective target constructor.
+    if (!constructor.isRedirectingGenerative) {
+      enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) {
+        if (field.initializer != null) {
+          fieldValues[field] = inlineExpression(field, field.initializer);
+        } else {
+          if (backend.isNativeOrExtendsNative(c)) {
+            // Native field is initialized elsewhere.
+          } else {
+            // Fields without an initializer default to null.
+            // This value will be overwritten below if an initializer is found.
+            fieldValues[field] = irBuilder.buildNullConstant();
+          }
+        }
+      });
+    }
+    // If this is a mixin constructor, it does not have its own parameter list
+    // or initializer list. Directly forward to the super constructor.
+    // Note that the declaration-site initializers originating from the
+    // mixed-in class were handled above.
+    if (enclosingClass.isMixinApplication) {
+      forwardSynthesizedMixinConstructor(constructor, supers, fieldValues);
+      return;
+    }
+    // Evaluate initializing parameters, e.g. `Foo(this.x)`.
+    constructor.functionSignature.orderedForEachParameter(
+        (ParameterElement parameter) {
+      if (parameter.isInitializingFormal) {
+        InitializingFormalElement fieldParameter = parameter;
+        fieldValues[fieldParameter.fieldElement] =
+            irBuilder.buildLocalGet(parameter);
+      }
+    });
+    // Evaluate constructor initializers, e.g. `Foo() : x = 50`.
+    ast.FunctionExpression node = constructor.node;
+    bool hasConstructorCall = false; // Has this() or super() initializer?
+    if (node != null && node.initializers != null) {
+      for(ast.Node initializer in node.initializers) {
+        if (initializer is ast.SendSet) {
+          // Field initializer.
+          FieldElement field = elements[initializer];
+          fieldValues[field] = visit(initializer.arguments.head);
+        } else if (initializer is ast.Send) {
+          // Super or this initializer.
+          ConstructorElement target = elements[initializer].implementation;
+          Selector selector = elements.getSelector(initializer);
+          List<ir.Primitive> arguments = initializer.arguments.mapToList(visit);
+          evaluateConstructorCallFromInitializer(
+              target,
+              selector.callStructure,
+              arguments,
+              supers,
+              fieldValues);
+          hasConstructorCall = true;
+        } else {
+          reporter.internalError(initializer,
+              "Unexpected initializer type $initializer");
+        }
+      }
+    }
+    // If no super() or this() was found, also call default superconstructor.
+    if (!hasConstructorCall && !enclosingClass.isObject) {
+      ClassElement superClass = enclosingClass.superclass;
+      FunctionElement target = superClass.lookupDefaultConstructor();
+      if (target == null) {
+        reporter.internalError(superClass, "No default constructor available.");
+      }
+      target = target.implementation;
+      evaluateConstructorCallFromInitializer(
+          target,
+          CallStructure.NO_ARGS,
+          const [],
+          supers,
+          fieldValues);
+    }
+    // Add this constructor after the superconstructors.
+    supers.add(constructor);
+  }
+
+  TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) {
+    TryBoxedVariables variables = new TryBoxedVariables(elements);
+    try {
+      variables.analyze(node);
+    } catch (e) {
+      bailoutMessage = variables.bailoutMessage;
+      rethrow;
+    }
+    return variables;
+  }
+
+  /// Builds the IR for the body of a constructor.
+  ///
+  /// This function is invoked from one or more "factory" constructors built by
+  /// [buildConstructor].
+  ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) {
+    ConstructorElement constructor = body.constructor;
+    ast.FunctionExpression node = constructor.node;
+    closureClassMap =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            constructor,
+            node,
+            elements);
+
+    // We compute variables boxed in mutable variables on entry to each try
+    // block, not including variables captured by a closure (which are boxed
+    // in the heap).  This duplicates some of the work of closure conversion
+    // without directly using the results.  This duplication is wasteful and
+    // error-prone.
+    // TODO(kmillikin): We should combine closure conversion and try/catch
+    // variable analysis in some way.
+    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
+    tryStatements = variables.tryStatements;
+    IrBuilder builder = getBuilderFor(body);
+
+    return withBuilder(builder, () {
+      irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body),
+          getClosureScopeForNode(node));
+      visit(node.body);
+      return irBuilder.makeFunctionDefinition();
+    });
+  }
+
+  ir.FunctionDefinition buildFunction(FunctionElement element) {
+    assert(invariant(element, element.isImplementation));
+    ast.FunctionExpression node = element.node;
+
+    assert(!element.isSynthesized);
+    assert(node != null);
+    assert(elements[node] != null);
+
+    closureClassMap =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            element,
+            node,
+            elements);
+    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
+    tryStatements = variables.tryStatements;
+    IrBuilder builder = getBuilderFor(element);
+    return withBuilder(builder, () => _makeFunctionBody(element, node));
+  }
+
+  ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) {
+    if (!backend.constants.lazyStatics.contains(element)) {
+      return null; // Nothing to do.
+    }
+    closureClassMap =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            element,
+            element.node,
+            elements);
+    IrBuilder builder = getBuilderFor(element);
+    return withBuilder(builder, () {
+      irBuilder.buildFunctionHeader(<Local>[]);
+      ir.Primitive initialValue = visit(element.initializer);
+      ast.VariableDefinitions node = element.node;
+      ast.SendSet sendSet = node.definitions.nodes.head;
+      irBuilder.buildReturn(
+          value: initialValue,
+          sourceInformation:
+          sourceInformationBuilder.buildReturn(sendSet.assignmentOperator));
+      return irBuilder.makeFunctionDefinition();
+    });
+  }
+
+  /// Builds the IR for a constant taken from a different [context].
+  ///
+  /// Such constants need to be compiled with a different [sourceFile] and
+  /// [elements] mapping.
+  ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
+    IrBuilderVisitor visitor = makeVisitorForContext(context);
+    return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
+  }
+
+  /// Creates a primitive for the default value of [parameter].
+  ir.Primitive translateDefaultValue(ParameterElement parameter) {
+    if (parameter.initializer == null) {
+      return irBuilder.buildNullConstant();
+    } else {
+      return inlineConstant(parameter.executableContext, parameter.initializer);
+    }
+  }
 
   /// Normalizes the argument list of a static invocation.
   ///
@@ -193,10 +804,43 @@
   /// that are not passed, and by sorting it in place so that named arguments
   /// appear in a canonical order.  A [CallStructure] reflecting this order
   /// is returned.
-  CallStructure normalizeStaticArguments(
-      CallStructure callStructure,
+  CallStructure normalizeStaticArguments(CallStructure callStructure,
       FunctionElement target,
-      List<ir.Primitive> arguments);
+      List<ir.Primitive> arguments) {
+    target = target.implementation;
+    FunctionSignature signature = target.functionSignature;
+    if (!signature.optionalParametersAreNamed &&
+        signature.parameterCount == arguments.length) {
+      return callStructure;
+    }
+
+    if (!signature.optionalParametersAreNamed) {
+      int i = signature.requiredParameterCount;
+      signature.forEachOptionalParameter((ParameterElement element) {
+        if (i < callStructure.positionalArgumentCount) {
+          ++i;
+        } else {
+          arguments.add(translateDefaultValue(element));
+        }
+      });
+      return new CallStructure(signature.parameterCount);
+    }
+
+    int offset = signature.requiredParameterCount;
+    List<ir.Primitive> namedArguments = arguments.sublist(offset);
+    arguments.length = offset;
+    List<String> normalizedNames = <String>[];
+    // Iterate over the optional parameters of the signature, and try to
+    // find them in the callStructure's named arguments. If found, we use the
+    // value in the temporary list, otherwise the default value.
+    signature.orderedOptionalParameters.forEach((ParameterElement element) {
+      int nameIndex = callStructure.namedArguments.indexOf(element.name);
+      arguments.add(nameIndex == -1 ? translateDefaultValue(element)
+          : namedArguments[nameIndex]);
+      normalizedNames.add(element.name);
+    });
+    return new CallStructure(signature.parameterCount, normalizedNames);
+  }
 
   /// Normalizes the argument list of a dynamic invocation.
   ///
@@ -204,12 +848,32 @@
   /// list [arguments] is normalized by sorting it in place so that the named
   /// arguments appear in a canonical order.  A [CallStructure] reflecting this
   /// order is returned.
-  CallStructure normalizeDynamicArguments(
-      CallStructure callStructure,
-      List<ir.Primitive> arguments);
+  CallStructure normalizeDynamicArguments(CallStructure callStructure,
+      List<ir.Primitive> arguments) {
+    assert(arguments.length == callStructure.argumentCount);
+    if (callStructure.namedArguments.isEmpty) return callStructure;
+    int destinationIndex = callStructure.positionalArgumentCount;
+    List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex);
+    for (String argName in callStructure.getOrderedNamedArguments()) {
+      int sourceIndex = callStructure.namedArguments.indexOf(argName);
+      arguments[destinationIndex++] = namedArguments[sourceIndex];
+    }
+    return new CallStructure(callStructure.argumentCount,
+        callStructure.getOrderedNamedArguments());
+  }
 
   /// Read the value of [field].
-  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src);
+  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
+    ConstantValue constant = getConstantForVariable(field);
+    if (constant != null && !field.isAssignable) {
+      typeMaskSystem.associateConstantValueWithElement(constant, field);
+      return irBuilder.buildConstant(constant, sourceInformation: src);
+    } else if (backend.constants.lazyStatics.contains(field)) {
+      return irBuilder.addPrimitive(new ir.GetLazyStatic(field, src));
+    } else {
+      return irBuilder.addPrimitive(new ir.GetStatic(field, src));
+    }
+  }
 
   ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
                                           ast.FunctionExpression node) {
@@ -221,7 +885,7 @@
     if (element.isFactoryConstructor) {
       // Type arguments are passed in as extra parameters.
       for (DartType typeVariable in element.enclosingClass.typeVariables) {
-        parameters.add(new TypeVariableLocal(typeVariable, element));
+        parameters.add(new closure.TypeVariableLocal(typeVariable, element));
       }
     }
 
@@ -233,17 +897,26 @@
     return irBuilder.makeFunctionDefinition();
   }
 
-  /// Returns the allocation site-specific type for a given allocation.
-  ///
-  /// Currently, it is an error to call this with anything that is not the
-  /// allocation site for a List object (a literal list or a call to one
-  /// of the List constructors).
-  TypeMask getAllocationSiteType(ast.Node node) {
-    return compiler.typesTask.getGuaranteedTypeOfNode(
-        elements.analyzedElement, node);
+  /// Builds the IR for creating an instance of the closure class corresponding
+  /// to the given nested function.
+  closure.ClosureClassElement makeSubFunction(ast.FunctionExpression node) {
+    closure.ClosureClassMap innerMap =
+        compiler.closureToClassMapper.getMappingForNestedFunction(node);
+    closure.ClosureClassElement closureClass = innerMap.closureClassElement;
+    return closureClass;
   }
 
-  ir.Primitive visit(ast.Node node) => node.accept(this);
+  ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
+    return irBuilder.buildFunctionExpression(makeSubFunction(node),
+        sourceInformationBuilder.buildCreate(node));
+  }
+
+  visitFunctionDeclaration(ast.FunctionDeclaration node) {
+    LocalFunctionElement element = elements[node.function];
+    Object inner = makeSubFunction(node.function);
+    irBuilder.declareLocalFunction(element, inner,
+        sourceInformationBuilder.buildCreate(node.function));
+  }
 
   // ## Statements ##
   visitBlock(ast.Block node) {
@@ -295,7 +968,7 @@
   /// constructor.  This is only required, if the forwarding factory
   /// constructor can potentially be the target of a reflective call, because
   /// the builder shortcuts calls to redirecting factories at the call site
-  /// (see [JsIrBuilderVisitor.handleConstructorInvoke]).
+  /// (see [handleConstructorInvoke]).
   visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
     ConstructorElement targetConstructor =
         elements.getRedirectingTargetConstructor(node).implementation;
@@ -392,13 +1065,15 @@
   }
 
   visitAwait(ast.Await node) {
+    assert(irBuilder.isOpen);
     ir.Primitive value = visit(node.expression);
-    return irBuilder.buildAwait(value);
+    return irBuilder.addPrimitive(new ir.Await(value));
   }
 
   visitYield(ast.Yield node) {
+    assert(irBuilder.isOpen);
     ir.Primitive value = visit(node.expression);
-    return irBuilder.buildYield(value, node.hasStar);
+    return irBuilder.addPrimitive(new ir.Yield(value, node.hasStar));
   }
 
   visitSyncForIn(ast.SyncForIn node) {
@@ -433,7 +1108,7 @@
   ir.Primitive checkType(ir.Primitive value, DartType dartType) {
     if (!compiler.trustTypeAnnotations) return value;
     TypeMask type = typeMaskSystem.subtypesOf(dartType).nullable();
-    return irBuilder.buildRefinement(value, type);
+    return irBuilder.addPrimitive(new ir.Refinement(value, type));
   }
 
   ir.Primitive checkTypeVsElement(ir.Primitive value, TypedElement element) {
@@ -472,7 +1147,7 @@
     SourceInformation source = sourceInformationBuilder.buildReturn(node);
     if (node.beginToken.value == 'native') {
       FunctionElement function = irBuilder.state.currentElement;
-      assert(compiler.backend.isNative(function));
+      assert(backend.isNative(function));
       ast.Node nativeBody = node.expression;
       if (nativeBody != null) {
         ast.LiteralString jsCode = nativeBody.asLiteralString();
@@ -486,7 +1161,6 @@
               'functions with zero parameters.'));
         irBuilder.buildNativeFunctionBody(function, javaScriptCode);
       } else {
-        JavaScriptBackend backend = compiler.backend;
         String name = backend.getFixedBackendName(function);
         irBuilder.buildRedirectingNativeFunctionBody(function, name, source);
       }
@@ -533,8 +1207,7 @@
     }
     ir.Primitive value = visit(node.expression);
     JumpTarget target = elements.getTargetDefinition(node);
-    Element error =
-        (compiler.backend as JavaScriptBackend).helpers.fallThroughError;
+    Element error = helpers.fallThroughError;
     irBuilder.buildSimpleSwitch(target, value, cases, defaultCase, error,
         sourceInformationBuilder.buildGeneric(node));
   }
@@ -636,6 +1309,16 @@
         sourceInformation: sourceInformation);
   }
 
+  /// Returns the allocation site-specific type for a given allocation.
+  ///
+  /// Currently, it is an error to call this with anything that is not the
+  /// allocation site for a List object (a literal list or a call to one
+  /// of the List constructors).
+  TypeMask getAllocationSiteType(ast.Node node) {
+    return compiler.typesTask.getGuaranteedTypeOfNode(
+        elements.analyzedElement, node);
+  }
+
   ir.Primitive visitLiteralList(ast.LiteralList node) {
     if (node.isConst) {
       return translateConstant(node);
@@ -647,15 +1330,16 @@
   }
 
   ir.Primitive visitLiteralMap(ast.LiteralMap node) {
+    assert(irBuilder.isOpen);
     if (node.isConst) {
       return translateConstant(node);
     }
     InterfaceType type = elements.getType(node);
-    return irBuilder.buildMapLiteral(
-        type,
-        node.entries.nodes.map((e) => e.key),
-        node.entries.nodes.map((e) => e.value),
-        build);
+    List<ir.LiteralMapEntry> entries =
+        node.entries.nodes.mapToList((ast.LiteralMapEntry e) {
+          return new ir.LiteralMapEntry(visit(e.key), visit(e.value));
+        });
+    return irBuilder.addPrimitive(new ir.LiteralMap(type, entries));
   }
 
   ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
@@ -706,7 +1390,21 @@
   // ## Sends ##
   @override
   void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
-    giveup(node, 'deferred access is not implemented');
+    if (prefix != null) buildCheckDeferredIsLoaded(prefix, node);
+  }
+
+  /// Create a call to check that a deferred import has already been loaded.
+  ir.Primitive buildCheckDeferredIsLoaded(PrefixElement prefix, ast.Send node) {
+    SourceInformation sourceInformation =
+        sourceInformationBuilder.buildCall(node, node.selector);
+    ir.Primitive name = irBuilder.buildStringConstant(
+        compiler.deferredLoadTask.getImportDeferName(node, prefix));
+    ir.Primitive uri =
+        irBuilder.buildStringConstant('${prefix.deferredImport.uri}');
+    return irBuilder.buildStaticFunctionInvocation(
+        helpers.checkDeferredIsLoaded,
+        <ir.Primitive>[name, uri],
+        sourceInformation: sourceInformation);
   }
 
   ir.Primitive visitNamedArgument(ast.NamedArgument node) {
@@ -793,23 +1491,14 @@
     return element.isConst
         ? irBuilder.buildConstant(getConstantForVariable(element),
             sourceInformation: sourceInformationBuilder.buildGet(node))
-        : irBuilder.buildLocalVariableGet(element);
+        : irBuilder.buildLocalGet(element);
   }
 
-  @override
   ir.Primitive handleLocalGet(
       ast.Send node,
       LocalElement element,
       _) {
-    return irBuilder.buildLocalVariableGet(element);
-  }
-
-  @override
-  ir.Primitive visitLocalFunctionGet(
-      ast.Send node,
-      LocalFunctionElement function,
-      _) {
-    return irBuilder.buildLocalFunctionGet(function);
+    return irBuilder.buildLocalGet(element);
   }
 
   @override
@@ -817,7 +1506,7 @@
       ast.Send node,
       MethodElement function,
       _) {
-    return irBuilder.buildStaticFunctionGet(function);
+    return irBuilder.addPrimitive(new ir.GetStatic(function));
   }
 
   @override
@@ -825,8 +1514,26 @@
       ast.Send node,
       FunctionElement getter,
       _) {
-    return irBuilder.buildStaticGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
+    return buildStaticGetterGet(getter, node);
+  }
+
+  /// Create a getter invocation of the static getter [getter]. This also
+  /// handles the special case where [getter] is the `loadLibrary`
+  /// pseudo-function on library prefixes of deferred imports.
+  ir.Primitive buildStaticGetterGet(MethodElement getter, ast.Send node) {
+    SourceInformation sourceInformation =
+        sourceInformationBuilder.buildGet(node);
+    if (getter.isDeferredLoaderGetter) {
+      PrefixElement prefix = getter.enclosingElement;
+      ir.Primitive loadId = irBuilder.buildStringConstant(
+          compiler.deferredLoadTask.getImportDeferName(node, prefix));
+      return irBuilder.buildStaticFunctionInvocation(
+          compiler.loadLibraryFunction,
+          <ir.Primitive>[loadId],
+          sourceInformation: sourceInformation);
+    } else {
+      return irBuilder.buildStaticGetterGet(getter, sourceInformation);
+    }
   }
 
   @override
@@ -1131,6 +1838,58 @@
   }
 
   @override
+  ir.Primitive handleConstructorInvoke(
+      ast.NewExpression node,
+      ConstructorElement constructor,
+      DartType type,
+      ast.NodeList argumentsNode,
+      CallStructure callStructure,
+      _) {
+
+    // TODO(sigmund): move these checks down after visiting arguments
+    // (see issue #25355)
+    ast.Send send = node.send;
+    // If an allocation refers to a type using a deferred import prefix (e.g.
+    // `new lib.A()`), we must ensure that the deferred import has already been
+    // loaded.
+    var prefix = compiler.deferredLoadTask.deferredPrefixElement(
+        send, elements);
+    if (prefix != null) buildCheckDeferredIsLoaded(prefix, send);
+
+    // We also emit deferred import checks when using redirecting factories that
+    // refer to deferred prefixes.
+    if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) {
+      ConstructorElement current = constructor;
+      while (current.isRedirectingFactory) {
+        var prefix = current.redirectionDeferredPrefix;
+        if (prefix != null) buildCheckDeferredIsLoaded(prefix, send);
+        current = current.immediateRedirectionTarget;
+      }
+    }
+
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+    // Use default values from the effective target, not the immediate target.
+    ConstructorElement target = constructor.effectiveTarget;
+
+    callStructure = normalizeStaticArguments(callStructure, target, arguments);
+    TypeMask allocationSiteType;
+
+    if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
+        Elements.isGrowableListConstructorCall(constructor, send, compiler) ||
+        Elements.isFilledListConstructorCall(constructor, send, compiler) ||
+        Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) {
+      allocationSiteType = getAllocationSiteType(send);
+    }
+    return irBuilder.buildConstructorInvocation(
+        target,
+        callStructure,
+        constructor.computeEffectiveTargetType(type),
+        arguments,
+        sourceInformationBuilder.buildNew(node),
+        allocationSiteType: allocationSiteType);
+  }
+
+  @override
   ir.Primitive handleDynamicInvoke(
       ast.Send node,
       ast.Node receiver,
@@ -1178,35 +1937,16 @@
       ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
+    ir.Primitive function = irBuilder.buildLocalGet(element);
     List<ir.Primitive> arguments = <ir.Primitive>[];
     callStructure =
         translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildLocalVariableInvocation(
-        element,
-        callStructure,
-        arguments,
-        callSourceInformation:
+    return irBuilder.buildCallInvocation(function, callStructure, arguments,
+        sourceInformation:
             sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
-  ir.Primitive visitLocalFunctionInvoke(
-      ast.Send node,
-      LocalFunctionElement function,
-      ast.NodeList argumentsNode,
-      CallStructure callStructure,
-      _) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildLocalFunctionInvocation(
-        function,
-        callStructure,
-        arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
   ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
     return buildStaticFieldGet(field, sourceInformationBuilder.buildGet(node));
   }
@@ -1232,12 +1972,22 @@
   }
 
   @override
-  ir.Primitive handleStaticFunctionInvoke(
-      ast.Send node,
+  ir.Primitive handleStaticFunctionInvoke(ast.Send node,
       MethodElement function,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
-      _);
+      _) {
+    if (compiler.backend.isForeign(function)) {
+      return handleForeignCode(node, function, argumentsNode, callStructure);
+    } else {
+      List<ir.Primitive> arguments = <ir.Primitive>[];
+      callStructure = translateStaticArguments(argumentsNode, function,
+          callStructure, arguments);
+      Selector selector = new Selector.call(function.memberName, callStructure);
+      return irBuilder.buildInvokeStatic(function, selector, arguments,
+          sourceInformationBuilder.buildCall(node, node.selector));
+    }
+  }
 
   @override
   ir.Primitive handleStaticFunctionIncompatibleInvoke(
@@ -1257,8 +2007,7 @@
       ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    ir.Primitive target = irBuilder.buildStaticGetterGet(getter,
-        sourceInformationBuilder.buildGet(node));
+    ir.Primitive target = buildStaticGetterGet(getter, node);
     List<ir.Primitive> arguments = <ir.Primitive>[];
     callStructure =
         translateDynamicArguments(argumentsNode, callStructure, arguments);
@@ -1410,9 +2159,9 @@
 
   ir.Primitive translateCompounds(
       ast.SendSet node,
-      {ir.Primitive getValue(),
-       CompoundRhs rhs,
-       void setValue(ir.Primitive value)}) {
+      ir.Primitive getValue(),
+      CompoundRhs rhs,
+      void setValue(ir.Primitive value)) {
     ir.Primitive value = getValue();
     op.BinaryOperator operator = rhs.operator;
     if (operator.kind == op.BinaryOperatorKind.IF_NULL) {
@@ -1453,9 +2202,9 @@
 
   ir.Primitive translateSetIfNull(
       ast.SendSet node,
-      {ir.Primitive getValue(),
-       ast.Node rhs,
-       void setValue(ir.Primitive value)}) {
+      ir.Primitive getValue(),
+      ast.Node rhs,
+      void setValue(ir.Primitive value)) {
     ir.Primitive value = getValue();
     // Unlike other compound operators if-null conditionally will not do the
     // assignment operation.
@@ -1514,7 +2263,9 @@
       FieldElement field,
       ast.Node rhs,
       _) {
-    return irBuilder.buildStaticFieldSet(field, visit(rhs));
+    ir.Primitive value = visit(rhs);
+    irBuilder.addPrimitive(new ir.SetStatic(field, value));
+    return value;
   }
 
   @override
@@ -1560,14 +2311,12 @@
       ConstantExpression constant,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          return buildConstantExpression(constant,
-            sourceInformationBuilder.buildGet(node));
-        },
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
+    SourceInformation src = sourceInformationBuilder.buildGet(node);
+    return translateCompounds(node, () {
+      return buildConstantExpression(constant, src);
+    }, rhs, (ir.Primitive value) {
+      // The binary operator will throw before this.
+    });
   }
 
   @override
@@ -1590,21 +2339,19 @@
       arg) {
     ir.Primitive target = translateReceiver(receiver);
     ir.Primitive helper() {
-      return translateCompounds(
-          node,
-          getValue: () => irBuilder.buildDynamicGet(
-              target,
-              new Selector.getter(name),
-              elements.getGetterTypeMaskInComplexSendSet(node),
-              sourceInformationBuilder.buildGet(node)),
-          rhs: rhs,
-          setValue: (ir.Primitive result) {
-            irBuilder.buildDynamicSet(
-                target,
-                new Selector.setter(name),
-                elements.getTypeMask(node),
-                result);
-          });
+      return translateCompounds(node, () {
+        return irBuilder.buildDynamicGet(
+            target,
+            new Selector.getter(name),
+            elements.getGetterTypeMaskInComplexSendSet(node),
+            sourceInformationBuilder.buildGet(node));
+      }, rhs, (ir.Primitive result) {
+        irBuilder.buildDynamicSet(
+            target,
+            new Selector.setter(name),
+            elements.getTypeMask(node),
+            result);
+      });
     }
     return node.isConditional
         ? irBuilder.buildIfNotNullSend(target, nested(helper))
@@ -1620,21 +2367,19 @@
       _) {
     ir.Primitive target = translateReceiver(receiver);
     ir.Primitive helper() {
-      return translateSetIfNull(
-          node,
-          getValue: () => irBuilder.buildDynamicGet(
-              target,
-              new Selector.getter(name),
-              elements.getGetterTypeMaskInComplexSendSet(node),
-              sourceInformationBuilder.buildGet(node)),
-          rhs: rhs,
-          setValue: (ir.Primitive result) {
-            irBuilder.buildDynamicSet(
-                target,
-                new Selector.setter(name),
-                elements.getTypeMask(node),
-                result);
-          });
+      return translateSetIfNull(node, () {
+        return irBuilder.buildDynamicGet(
+            target,
+            new Selector.getter(name),
+            elements.getGetterTypeMaskInComplexSendSet(node),
+            sourceInformationBuilder.buildGet(node));
+      }, rhs, (ir.Primitive result) {
+        irBuilder.buildDynamicSet(
+            target,
+            new Selector.setter(name),
+            elements.getTypeMask(node),
+            result);
+      });
     }
     return node.isConditional
         ? irBuilder.buildIfNotNullSend(target, nested(helper))
@@ -1654,23 +2399,17 @@
       CompoundRhs rhs,
       arg,
       {bool isSetterValid}) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          if (local.isFunction) {
-            return irBuilder.buildLocalFunctionGet(local);
-          } else {
-            return irBuilder.buildLocalVariableGet(local);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildLocalVariableSet(local, result);
-          } else {
-            return buildLocalNoSuchSetter(local, result);
-          }
-        });
+    return translateCompounds(node, () {
+      return irBuilder.buildLocalGet(local);
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        irBuilder.buildLocalVariableSet(local, result);
+      } else {
+        Selector selector = new Selector.setter(
+            new Name(local.name, local.library, isSetter: true));
+        irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result]);
+      }
+    });
   }
 
   @override
@@ -1680,35 +2419,17 @@
       ast.Node rhs,
       _,
       {bool isSetterValid}) {
-    return translateSetIfNull(
-        node,
-        getValue: () {
-          if (local.isFunction) {
-            return irBuilder.buildLocalFunctionGet(local);
-          } else {
-            return irBuilder.buildLocalVariableGet(local);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildLocalVariableSet(local, result);
-          } else {
-            return buildLocalNoSuchSetter(local, result);
-          }
-        });
-  }
-
-  ir.Primitive buildStaticNoSuchGetter(Element element) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.getter(new Name(element.name, element.library)),
-        const <ir.Primitive>[]);
-  }
-
-  ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(new Name(element.name, element.library)),
-        <ir.Primitive>[value]);
+    return translateSetIfNull(node, () {
+      return irBuilder.buildLocalGet(local);
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        irBuilder.buildLocalVariableSet(local, result);
+      } else {
+        Selector selector = new Selector.setter(
+            new Name(local.name, local.library, isSetter: true));
+        irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result]);
+      }
+    });
   }
 
   @override
@@ -1720,33 +2441,35 @@
       CompoundSetter setterKind,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              SourceInformation src = sourceInformationBuilder.buildGet(node);
-              return buildStaticFieldGet(getter, src);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildStaticGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildStaticFunctionGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildStaticNoSuchGetter(getter);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              return irBuilder.buildStaticFieldSet(setter, result);
-            case CompoundSetter.SETTER:
-              return irBuilder.buildStaticSetterSet(setter, result);
-            case CompoundSetter.INVALID:
-              return buildStaticNoSuchSetter(setter, result);
-          }
-        });
+    return translateCompounds(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          SourceInformation src = sourceInformationBuilder.buildGet(node);
+          return buildStaticFieldGet(getter, src);
+        case CompoundGetter.GETTER:
+          return buildStaticGetterGet(getter, node);
+        case CompoundGetter.METHOD:
+          return irBuilder.addPrimitive(new ir.GetStatic(getter));
+        case CompoundGetter.UNRESOLVED:
+          return irBuilder.buildStaticNoSuchMethod(
+              new Selector.getter(new Name(getter.name, getter.library)),
+              <ir.Primitive>[]);
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.addPrimitive(new ir.SetStatic(setter, result));
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildStaticSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          irBuilder.buildStaticNoSuchMethod(
+              new Selector.setter(new Name(setter.name, setter.library)),
+              <ir.Primitive>[result]);
+          return;
+      }
+    });
   }
 
   @override
@@ -1758,33 +2481,35 @@
       CompoundSetter setterKind,
       ast.Node rhs,
       _) {
-    return translateSetIfNull(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              SourceInformation src = sourceInformationBuilder.buildGet(node);
-              return buildStaticFieldGet(getter, src);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildStaticGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildStaticFunctionGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildStaticNoSuchGetter(getter);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              return irBuilder.buildStaticFieldSet(setter, result);
-            case CompoundSetter.SETTER:
-              return irBuilder.buildStaticSetterSet(setter, result);
-            case CompoundSetter.INVALID:
-              return buildStaticNoSuchSetter(setter, result);
-          }
-        });
+    return translateSetIfNull(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          SourceInformation src = sourceInformationBuilder.buildGet(node);
+          return buildStaticFieldGet(getter, src);
+        case CompoundGetter.GETTER:
+          return buildStaticGetterGet(getter, node);
+        case CompoundGetter.METHOD:
+          return irBuilder.addPrimitive(new ir.GetStatic(getter));
+        case CompoundGetter.UNRESOLVED:
+          return irBuilder.buildStaticNoSuchMethod(
+              new Selector.getter(new Name(getter.name, getter.library)),
+              <ir.Primitive>[]);
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.addPrimitive(new ir.SetStatic(setter, result));
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildStaticSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          irBuilder.buildStaticNoSuchMethod(
+              new Selector.setter(new Name(setter.name, setter.library)),
+              <ir.Primitive>[result]);
+          return;
+      }
+    });
   }
 
   ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) {
@@ -1812,35 +2537,33 @@
       CompoundSetter setterKind,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return irBuilder.buildSuperFieldGet(getter);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildSuperGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildSuperMethodGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildSuperNoSuchGetter(
-                  getter,
-                  elements.getGetterTypeMaskInComplexSendSet(node));
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              return irBuilder.buildSuperFieldSet(setter, result);
-            case CompoundSetter.SETTER:
-              return irBuilder.buildSuperSetterSet(setter, result);
-            case CompoundSetter.INVALID:
-              return buildSuperNoSuchSetter(
-                  setter, elements.getTypeMask(node), result);
-          }
-        });
+    return translateCompounds(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          return irBuilder.buildSuperFieldGet(getter);
+        case CompoundGetter.GETTER:
+          return irBuilder.buildSuperGetterGet(
+              getter, sourceInformationBuilder.buildGet(node));
+        case CompoundGetter.METHOD:
+          return irBuilder.buildSuperMethodGet(getter);
+        case CompoundGetter.UNRESOLVED:
+          return buildSuperNoSuchGetter(
+              getter, elements.getGetterTypeMaskInComplexSendSet(node));
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.buildSuperFieldSet(setter, result);
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildSuperSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          buildSuperNoSuchSetter(
+              setter, elements.getTypeMask(node), result);
+          return;
+      }
+    });
   }
 
   @override
@@ -1852,35 +2575,34 @@
       CompoundSetter setterKind,
       ast.Node rhs,
       _) {
-    return translateSetIfNull(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return irBuilder.buildSuperFieldGet(getter);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildSuperGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildSuperMethodGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildSuperNoSuchGetter(
-                  getter,
-                  elements.getGetterTypeMaskInComplexSendSet(node));
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              return irBuilder.buildSuperFieldSet(setter, result);
-            case CompoundSetter.SETTER:
-              return irBuilder.buildSuperSetterSet(setter, result);
-            case CompoundSetter.INVALID:
-              return buildSuperNoSuchSetter(
-                  setter, elements.getTypeMask(node), result);
-          }
-        });
+    return translateSetIfNull(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          return irBuilder.buildSuperFieldGet(getter);
+        case CompoundGetter.GETTER:
+          return irBuilder.buildSuperGetterGet(
+              getter, sourceInformationBuilder.buildGet(node));
+        case CompoundGetter.METHOD:
+          return irBuilder.buildSuperMethodGet(getter);
+        case CompoundGetter.UNRESOLVED:
+          return buildSuperNoSuchGetter(
+              getter,
+              elements.getGetterTypeMaskInComplexSendSet(node));
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.buildSuperFieldSet(setter, result);
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildSuperSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          buildSuperNoSuchSetter(
+              setter, elements.getTypeMask(node), result);
+          return;
+      }
+    });
   }
 
   @override
@@ -1889,15 +2611,13 @@
       TypeVariableElement typeVariable,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          return irBuilder.buildReifyTypeVariable(
-            typeVariable.type,
-            sourceInformationBuilder.buildGet(node));
-        },
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
+    return translateCompounds(node, () {
+      return irBuilder.buildReifyTypeVariable(
+          typeVariable.type,
+          sourceInformationBuilder.buildGet(node));
+    }, rhs, (ir.Primitive value) {
+      // The binary operator will throw before this.
+    });
   }
 
   @override
@@ -1920,29 +2640,25 @@
       arg) {
     ir.Primitive target = visit(receiver);
     ir.Primitive indexValue = visit(index);
-    return translateCompounds(
-        node,
-        getValue: () {
-          Selector selector = new Selector.index();
-          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
-          CallStructure callStructure =
-              normalizeDynamicArguments(selector.callStructure, arguments);
-          return irBuilder.buildDynamicInvocation(
-              target,
-              new Selector(selector.kind, selector.memberName, callStructure),
-              elements.getGetterTypeMaskInComplexSendSet(node),
-              arguments,
-              sourceInformation:
-                  sourceInformationBuilder.buildCall(receiver, node));
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildDynamicIndexSet(
-              target,
-              elements.getTypeMask(node),
-              indexValue,
-              result);
-        });
+    return translateCompounds(node, () {
+      Selector selector = new Selector.index();
+      List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+      CallStructure callStructure =
+          normalizeDynamicArguments(selector.callStructure, arguments);
+      return irBuilder.buildDynamicInvocation(
+          target,
+          new Selector(selector.kind, selector.memberName, callStructure),
+          elements.getGetterTypeMaskInComplexSendSet(node),
+          arguments,
+          sourceInformation:
+          sourceInformationBuilder.buildCall(receiver, node));
+    }, rhs, (ir.Primitive result) {
+      irBuilder.buildDynamicIndexSet(
+          target,
+          elements.getTypeMask(node),
+          indexValue,
+          result);
+    });
   }
 
   @override
@@ -1956,29 +2672,260 @@
       {bool isGetterValid,
        bool isSetterValid}) {
     ir.Primitive indexValue = visit(index);
-    return translateCompounds(
-        node,
-        getValue: () {
-          if (isGetterValid) {
-            return irBuilder.buildSuperIndex(indexFunction, indexValue);
-          } else {
-            return buildInstanceNoSuchMethod(
-                new Selector.index(),
-                elements.getGetterTypeMaskInComplexSendSet(node),
-                <ir.Primitive>[indexValue]);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
-          } else {
-            buildInstanceNoSuchMethod(
-                new Selector.indexSet(),
-                elements.getTypeMask(node),
-                <ir.Primitive>[indexValue, result]);
-          }
-        });
+    return translateCompounds(node, () {
+      return isGetterValid
+          ? irBuilder.buildSuperIndex(indexFunction, indexValue)
+          : buildInstanceNoSuchMethod(
+              new Selector.index(),
+              elements.getGetterTypeMaskInComplexSendSet(node),
+              <ir.Primitive>[indexValue]);
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
+      } else {
+        buildInstanceNoSuchMethod(
+            new Selector.indexSet(),
+            elements.getTypeMask(node),
+            <ir.Primitive>[indexValue, result]);
+      }
+    });
+  }
+
+  /// Build code to handle foreign code, that is, native JavaScript code, or
+  /// builtin values and operations of the backend.
+  ir.Primitive handleForeignCode(ast.Send node,
+      MethodElement function,
+      ast.NodeList argumentList,
+      CallStructure callStructure) {
+
+    void validateArgumentCount({int minimum, int exactly}) {
+      assert((minimum == null) != (exactly == null));
+      int count = 0;
+      int maximum;
+      if (exactly != null) {
+        minimum = exactly;
+        maximum = exactly;
+      }
+      for (ast.Node argument in argumentList) {
+        count++;
+        if (maximum != null && count > maximum) {
+          internalError(argument, 'Additional argument.');
+        }
+      }
+      if (count < minimum) {
+        internalError(node, 'Expected at least $minimum arguments.');
+      }
+    }
+
+    /// Call a helper method from the isolate library. The isolate library uses
+    /// its own isolate structure, that encapsulates dart2js's isolate.
+    ir.Primitive buildIsolateHelperInvocation(MethodElement element,
+        CallStructure callStructure) {
+      if (element == null) {
+        reporter.internalError(node,
+            'Isolate library and compiler mismatch.');
+      }
+      List<ir.Primitive> arguments = <ir.Primitive>[];
+      callStructure = translateStaticArguments(argumentList, element,
+          callStructure, arguments);
+      Selector selector = new Selector.call(element.memberName, callStructure);
+      return irBuilder.buildInvokeStatic(element, selector, arguments,
+          sourceInformationBuilder.buildCall(node, node.selector));
+    }
+
+    /// Lookup the value of the enum described by [node].
+    getEnumValue(ast.Node node, EnumClassElement enumClass, List values) {
+      Element element = elements[node];
+      if (element is! FieldElement || element.enclosingClass != enumClass) {
+        internalError(node, 'expected a JsBuiltin enum value');
+      }
+
+      int index = enumClass.enumValues.indexOf(element);
+      return values[index];
+    }
+
+    /// Returns the String the node evaluates to, or throws an error if the
+    /// result is not a string constant.
+    String expectStringConstant(ast.Node node) {
+      ir.Primitive nameValue = visit(node);
+      if (nameValue is ir.Constant && nameValue.value.isString) {
+        StringConstantValue constantValue = nameValue.value;
+        return constantValue.primitiveValue.slowToString();
+      } else {
+        return internalError(node, 'expected a literal string');
+      }
+    }
+
+    Link<ast.Node> argumentNodes  = argumentList.nodes;
+    NativeBehavior behavior =
+    compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+    switch (function.name) {
+      case 'JS':
+        validateArgumentCount(minimum: 2);
+        // The first two arguments are the type and the foreign code template,
+        // which already have been analyzed by the resolver and can be retrieved
+        // using [NativeBehavior]. We can ignore these arguments in the backend.
+        List<ir.Primitive> arguments =
+        argumentNodes.skip(2).mapToList(visit, growable: false);
+        if (behavior.codeTemplate.positionalArgumentCount != arguments.length) {
+          reporter.reportErrorMessage(
+              node, MessageKind.GENERIC,
+              {'text':
+              'Mismatch between number of placeholders'
+                  ' and number of arguments.'});
+          return irBuilder.buildNullConstant();
+        }
+
+        if (HasCapturedPlaceholders.check(behavior.codeTemplate.ast)) {
+          reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
+          return irBuilder.buildNullConstant();
+        }
+
+        return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
+            behavior);
+
+      case 'DART_CLOSURE_TO_JS':
+      // TODO(ahe): This should probably take care to wrap the closure in
+      // another closure that saves the current isolate.
+      case 'RAW_DART_FUNCTION_REF':
+        validateArgumentCount(exactly: 1);
+
+        ast.Node argument = node.arguments.single;
+        FunctionElement closure = elements[argument].implementation;
+        if (!Elements.isStaticOrTopLevelFunction(closure)) {
+          internalError(argument,
+              'only static or toplevel function supported');
+        }
+        if (closure.functionSignature.hasOptionalParameters) {
+          internalError(argument,
+              'closures with optional parameters not supported');
+        }
+        return irBuilder.buildForeignCode(
+            js.js.expressionTemplateYielding(
+                backend.emitter.staticFunctionAccess(closure)),
+            <ir.Primitive>[],
+            NativeBehavior.PURE,
+            dependency: closure);
+
+      case 'JS_BUILTIN':
+      // The first argument is a description of the type and effect of the
+      // builtin, which has already been analyzed in the frontend.  The second
+      // argument must be a [JsBuiltin] value.  All other arguments are
+      // values used by the JavaScript template that is associated with the
+      // builtin.
+        validateArgumentCount(minimum: 2);
+
+        ast.Node builtin = argumentNodes.tail.head;
+        JsBuiltin value = getEnumValue(builtin, helpers.jsBuiltinEnum,
+            JsBuiltin.values);
+        js.Template template = backend.emitter.builtinTemplateFor(value);
+        List<ir.Primitive> arguments =
+        argumentNodes.skip(2).mapToList(visit, growable: false);
+        return irBuilder.buildForeignCode(template, arguments, behavior);
+
+      case 'JS_EMBEDDED_GLOBAL':
+        validateArgumentCount(exactly: 2);
+
+        String name = expectStringConstant(argumentNodes.tail.head);
+        js.Expression access =
+        backend.emitter.generateEmbeddedGlobalAccess(name);
+        js.Template template = js.js.expressionTemplateYielding(access);
+        return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior);
+
+      case 'JS_INTERCEPTOR_CONSTANT':
+        validateArgumentCount(exactly: 1);
+
+        ast.Node argument = argumentNodes.head;
+        ir.Primitive argumentValue = visit(argument);
+        if (argumentValue is ir.Constant && argumentValue.value.isType) {
+          TypeConstantValue constant = argumentValue.value;
+          ConstantValue interceptorValue =
+          new InterceptorConstantValue(constant.representedType);
+          return irBuilder.buildConstant(interceptorValue);
+        }
+        return internalError(argument, 'expected Type as argument');
+
+      case 'JS_EFFECT':
+        return irBuilder.buildNullConstant();
+
+      case 'JS_GET_NAME':
+        validateArgumentCount(exactly: 1);
+
+        ast.Node argument = argumentNodes.head;
+        JsGetName id = getEnumValue(argument, helpers.jsGetNameEnum,
+            JsGetName.values);
+        js.Name name = backend.namer.getNameForJsGetName(argument, id);
+        ConstantValue nameConstant =
+        new SyntheticConstantValue(SyntheticConstantKind.NAME,
+            js.js.quoteName(name));
+
+        return irBuilder.buildConstant(nameConstant);
+
+      case 'JS_GET_FLAG':
+        validateArgumentCount(exactly: 1);
+
+        String name = expectStringConstant(argumentNodes.first);
+        bool value = false;
+        switch (name) {
+          case 'MUST_RETAIN_METADATA':
+            value = backend.mustRetainMetadata;
+            break;
+          case 'USE_CONTENT_SECURITY_POLICY':
+            value = compiler.useContentSecurityPolicy;
+            break;
+          default:
+            internalError(node, 'Unknown internal flag "$name".');
+        }
+        return irBuilder.buildBooleanConstant(value);
+
+      case 'JS_STRING_CONCAT':
+        validateArgumentCount(exactly: 2);
+        List<ir.Primitive> arguments = argumentNodes.mapToList(visit);
+        return irBuilder.buildStringConcatenation(arguments);
+
+      case 'JS_CURRENT_ISOLATE_CONTEXT':
+        validateArgumentCount(exactly: 0);
+
+        if (!compiler.hasIsolateSupport) {
+          // If the isolate library is not used, we just generate code
+          // to fetch the current isolate.
+          continue getStaticState;
+        }
+        return buildIsolateHelperInvocation(helpers.currentIsolate,
+            CallStructure.NO_ARGS);
+
+      getStaticState: case 'JS_GET_STATIC_STATE':
+        validateArgumentCount(exactly: 0);
+
+        return irBuilder.buildForeignCode(
+            js.js.parseForeignJS(backend.namer.staticStateHolder),
+            const <ir.Primitive>[],
+            NativeBehavior.PURE);
+
+      case 'JS_SET_STATIC_STATE':
+        validateArgumentCount(exactly: 1);
+
+        ir.Primitive value = visit(argumentNodes.single);
+        String isolateName = backend.namer.staticStateHolder;
+        return irBuilder.buildForeignCode(
+            js.js.parseForeignJS("$isolateName = #"),
+            <ir.Primitive>[value],
+            NativeBehavior.PURE);
+
+      case 'JS_CALL_IN_ISOLATE':
+        validateArgumentCount(exactly: 2);
+
+        if (!compiler.hasIsolateSupport) {
+          ir.Primitive closure = visit(argumentNodes.tail.head);
+          return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
+              const <ir.Primitive>[]);
+        }
+        return buildIsolateHelperInvocation(helpers.callInIsolate,
+            CallStructure.TWO_ARGS);
+
+      default:
+        return giveup(node, 'unplemented native construct: ${function.name}');
+    }
   }
 
   /// Evaluates a string interpolation and appends each part to [accumulator]
@@ -2003,7 +2950,9 @@
       buildStringParts(node.expression, accumulator);
     } else {
       ir.Primitive value = visit(node);
-      accumulator.add(irBuilder.buildStringify(value));
+      accumulator.add(irBuilder.buildStaticFunctionInvocation(
+          helpers.stringInterpolationHelper,
+          <ir.Primitive>[value]));
     }
   }
 
@@ -2035,14 +2984,15 @@
     return irBuilder.buildNonTailThrow(visit(node.expression));
   }
 
-  ir.Primitive buildInstanceNoSuchMethod(
-      Selector selector,
+  ir.Primitive buildInstanceNoSuchMethod(Selector selector,
       TypeMask mask,
-      List<ir.Primitive> arguments);
-
-  ir.Primitive buildRuntimeError(String message);
-
-  ir.Primitive buildAbstractClassInstantiationError(ClassElement element);
+      List<ir.Primitive> arguments) {
+    return irBuilder.buildDynamicInvocation(
+        irBuilder.buildThis(),
+        Selectors.noSuchMethod_,
+        mask,
+        [irBuilder.buildInvocationMirror(selector, arguments)]);
+  }
 
   @override
   ir.Primitive visitUnresolvedCompound(
@@ -2063,7 +3013,11 @@
       ast.NodeList arguments,
       Selector selector, _) {
     // If the class is missing it's a runtime error.
-    return buildRuntimeError("Unresolved class: '${element.name}'");
+    ir.Primitive message =
+        irBuilder.buildStringConstant("Unresolved class: '${element.name}'");
+    return irBuilder.buildStaticFunctionInvocation(
+        helpers.throwRuntimeError,
+        <ir.Primitive>[message]);
   }
 
   @override
@@ -2230,7 +3184,11 @@
       ast.NodeList arguments,
       CallStructure callStructure, _) {
     for (ast.Node argument in arguments) visit(argument);
-    return buildAbstractClassInstantiationError(element.enclosingClass);
+    ir.Primitive name =
+        irBuilder.buildStringConstant(element.enclosingClass.name);
+    return irBuilder.buildStaticFunctionInvocation(
+        helpers.throwAbstractClassInstantiationError,
+        <ir.Primitive>[name]);
   }
 
   @override
@@ -2572,10 +3530,6 @@
     return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
   }
 
-  FunctionElement get stringifyFunction {
-    return _backend.helpers.stringInterpolationHelper;
-  }
-
   FunctionElement get throwTypeErrorHelper => _backend.helpers.throwTypeError;
   Element get throwNoSuchMethod => _backend.helpers.throwNoSuchMethod;
 
@@ -2602,1072 +3556,3 @@
     _backend.emitter.nativeEmitter.nativeMethods.add(function);
   }
 }
-
-/// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
-class JsIrBuilderVisitor extends IrBuilderVisitor {
-  JavaScriptBackend get backend => compiler.backend;
-
-  /// Result of closure conversion for the current body of code.
-  ///
-  /// Will be initialized upon entering the body of a function.
-  /// It is computed by the [ClosureTranslator].
-  ClosureClassMap closureClassMap;
-
-  JsIrBuilderVisitor(TreeElements elements,
-                     Compiler compiler,
-                     SourceInformationBuilder sourceInformationBuilder,
-                     TypeMaskSystem typeMaskSystem)
-      : super(elements, compiler, sourceInformationBuilder, typeMaskSystem);
-
-  BackendHelpers get helpers => backend.helpers;
-
-  /// Builds the IR for creating an instance of the closure class corresponding
-  /// to the given nested function.
-  ClosureClassElement makeSubFunction(ast.FunctionExpression node) {
-    ClosureClassMap innerMap =
-        compiler.closureToClassMapper.getMappingForNestedFunction(node);
-    ClosureClassElement closureClass = innerMap.closureClassElement;
-    return closureClass;
-  }
-
-  ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
-    return irBuilder.buildFunctionExpression(makeSubFunction(node),
-        sourceInformationBuilder.buildCreate(node));
-  }
-
-  visitFunctionDeclaration(ast.FunctionDeclaration node) {
-    LocalFunctionElement element = elements[node.function];
-    Object inner = makeSubFunction(node.function);
-    irBuilder.declareLocalFunction(element, inner,
-        sourceInformationBuilder.buildCreate(node.function));
-  }
-
-  Map mapValues(Map map, dynamic fn(dynamic)) {
-    Map result = {};
-    map.forEach((key, value) {
-      result[key] = fn(value);
-    });
-    return result;
-  }
-
-  /// Converts closure.dart's CapturedVariable into a ClosureLocation.
-  /// There is a 1:1 corresponce between these; we do this because the
-  /// IR builder should not depend on synthetic elements.
-  ClosureLocation getLocation(CapturedVariable v) {
-    if (v is BoxFieldElement) {
-      return new ClosureLocation(v.box, v);
-    } else {
-      ClosureFieldElement field = v;
-      return new ClosureLocation(null, field);
-    }
-  }
-
-  /// If the current function is a nested function with free variables (or a
-  /// captured reference to `this`), returns a [ClosureEnvironment]
-  /// indicating how to access these.
-  ClosureEnvironment getClosureEnvironment() {
-    if (closureClassMap.closureElement == null) return null;
-    return new ClosureEnvironment(
-        closureClassMap.closureElement,
-        closureClassMap.thisLocal,
-        mapValues(closureClassMap.freeVariableMap, getLocation));
-  }
-
-  /// If [node] has declarations for variables that should be boxed,
-  /// returns a [ClosureScope] naming a box to create, and enumerating the
-  /// variables that should be stored in the box.
-  ///
-  /// Also see [ClosureScope].
-  ClosureScope getClosureScopeForNode(ast.Node node) {
-    closurelib.ClosureScope scope = closureClassMap.capturingScopes[node];
-    if (scope == null) return null;
-    // We translate a ClosureScope from closure.dart into IR builder's variant
-    // because the IR builder should not depend on the synthetic elements
-    // created in closure.dart.
-    return new ClosureScope(scope.boxElement,
-                            mapValues(scope.capturedVariables, getLocation),
-                            scope.boxedLoopVariables);
-  }
-
-  /// Returns the [ClosureScope] for any function, possibly different from the
-  /// one currently being built.
-  ClosureScope getClosureScopeForFunction(FunctionElement function) {
-    ClosureClassMap map =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            function,
-            function.node,
-            elements);
-    closurelib.ClosureScope scope = map.capturingScopes[function.node];
-    if (scope == null) return null;
-    return new ClosureScope(scope.boxElement,
-                            mapValues(scope.capturedVariables, getLocation),
-                            scope.boxedLoopVariables);
-  }
-
-  ir.FunctionDefinition buildExecutable(ExecutableElement element) {
-    return nullIfGiveup(() {
-      ir.FunctionDefinition root;
-      switch (element.kind) {
-        case ElementKind.GENERATIVE_CONSTRUCTOR:
-          root = buildConstructor(element);
-          break;
-
-        case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
-          root = buildConstructorBody(element);
-          break;
-
-        case ElementKind.FACTORY_CONSTRUCTOR:
-        case ElementKind.FUNCTION:
-        case ElementKind.GETTER:
-        case ElementKind.SETTER:
-          root = buildFunction(element);
-          break;
-
-        case ElementKind.FIELD:
-          if (Elements.isStaticOrTopLevel(element)) {
-            root = buildStaticFieldInitializer(element);
-          } else {
-            // Instance field initializers are inlined in the constructor,
-            // so we shouldn't need to build anything here.
-            // TODO(asgerf): But what should we return?
-            return null;
-          }
-          break;
-
-        default:
-          reporter.internalError(element, "Unexpected element type $element");
-      }
-      return root;
-    });
-  }
-
-  ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) {
-    if (!backend.constants.lazyStatics.contains(element)) {
-      return null; // Nothing to do.
-    }
-    closureClassMap =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            element,
-            element.node,
-            elements);
-    IrBuilder builder = getBuilderFor(element);
-    return withBuilder(builder, () {
-      irBuilder.buildFunctionHeader(<Local>[]);
-      ir.Primitive initialValue = visit(element.initializer);
-      ast.VariableDefinitions node = element.node;
-      ast.SendSet sendSet = node.definitions.nodes.head;
-      irBuilder.buildReturn(
-          value: initialValue,
-          sourceInformation:
-              sourceInformationBuilder.buildReturn(sendSet.assignmentOperator));
-      return irBuilder.makeFunctionDefinition();
-    });
-  }
-
-  /// Make a visitor suitable for translating ASTs taken from [context].
-  ///
-  /// Every visitor can only be applied to nodes in one context, because
-  /// the [elements] field is specific to that context.
-  JsIrBuilderVisitor makeVisitorForContext(AstElement context) {
-    return new JsIrBuilderVisitor(
-        context.resolvedAst.elements,
-        compiler,
-        sourceInformationBuilder.forContext(context),
-        typeMaskSystem);
-  }
-
-  /// Builds the IR for an [expression] taken from a different [context].
-  ///
-  /// Such expressions need to be compiled with a different [sourceFile] and
-  /// [elements] mapping.
-  ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
-    JsIrBuilderVisitor visitor = makeVisitorForContext(context);
-    return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
-  }
-
-  /// Builds the IR for a constant taken from a different [context].
-  ///
-  /// Such constants need to be compiled with a different [sourceFile] and
-  /// [elements] mapping.
-  ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
-    JsIrBuilderVisitor visitor = makeVisitorForContext(context);
-    return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
-  }
-
-  IrBuilder getBuilderFor(Element element) {
-    return new IrBuilder(
-        new GlobalProgramInformation(compiler),
-        compiler.backend.constants,
-        element);
-  }
-
-  /// Builds the IR for a given constructor.
-  ///
-  /// 1. Computes the type held in all own or "inherited" type variables.
-  /// 2. Evaluates all own or inherited field initializers.
-  /// 3. Creates the object and assigns its fields and runtime type.
-  /// 4. Calls constructor body and super constructor bodies.
-  /// 5. Returns the created object.
-  ir.FunctionDefinition buildConstructor(ConstructorElement constructor) {
-    // TODO(asgerf): Optimization: If constructor is redirecting, then just
-    //               evaluate arguments and call the target constructor.
-    constructor = constructor.implementation;
-    ClassElement classElement = constructor.enclosingClass.implementation;
-
-    IrBuilder builder = getBuilderFor(constructor);
-
-    final bool requiresTypeInformation =
-        builder.program.requiresRuntimeTypesFor(classElement);
-
-    return withBuilder(builder, () {
-      // Setup parameters and create a box if anything is captured.
-      List<Local> parameters = <Local>[];
-      constructor.functionSignature.orderedForEachParameter(
-          (ParameterElement p) => parameters.add(p));
-
-      int firstTypeArgumentParameterIndex;
-
-      // If instances of the class may need runtime type information, we add a
-      // synthetic parameter for each type parameter.
-      if (requiresTypeInformation) {
-        firstTypeArgumentParameterIndex = parameters.length;
-        classElement.typeVariables.forEach((TypeVariableType variable) {
-          parameters.add(new TypeVariableLocal(variable, constructor));
-        });
-      } else {
-        classElement.typeVariables.forEach((TypeVariableType variable) {
-          irBuilder.declareTypeVariable(variable, const DynamicType());
-        });
-      }
-
-      // Create IR parameters and setup the environment.
-      List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters,
-          closureScope: getClosureScopeForFunction(constructor));
-
-      // Create a list of the values of all type argument parameters, if any.
-      List<ir.Primitive> typeInformation;
-      if (requiresTypeInformation) {
-        typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex);
-      } else {
-        typeInformation = const <ir.Primitive>[];
-      }
-
-      // -- Load values for type variables declared on super classes --
-      // Field initializers for super classes can reference these, so they
-      // must be available before evaluating field initializers.
-      // This could be interleaved with field initialization, but we choose do
-      // get it out of the way here to avoid complications with mixins.
-      loadTypeVariablesForSuperClasses(classElement);
-
-      /// Maps each field from this class or a superclass to its initial value.
-      Map<FieldElement, ir.Primitive> fieldValues =
-          <FieldElement, ir.Primitive>{};
-
-      // -- Evaluate field initializers ---
-      // Evaluate field initializers in constructor and super constructors.
-      List<ConstructorElement> constructorList = <ConstructorElement>[];
-      evaluateConstructorFieldInitializers(
-          constructor, constructorList, fieldValues);
-
-      // All parameters in all constructors are now bound in the environment.
-      // BoxLocals for captured parameters are also in the environment.
-      // The initial value of all fields are now bound in [fieldValues].
-
-      // --- Create the object ---
-      // Get the initial field values in the canonical order.
-      List<ir.Primitive> instanceArguments = <ir.Primitive>[];
-      classElement.forEachInstanceField((ClassElement c, FieldElement field) {
-        ir.Primitive value = fieldValues[field];
-        if (value != null) {
-          instanceArguments.add(value);
-        } else {
-          assert(backend.isNativeOrExtendsNative(c));
-          // Native fields are initialized elsewhere.
-        }
-      }, includeSuperAndInjectedMembers: true);
-
-      ir.Primitive instance = new ir.CreateInstance(
-          classElement,
-          instanceArguments,
-          typeInformation,
-          constructor.hasNode
-              ? sourceInformationBuilder.buildCreate(constructor.node)
-              // TODO(johnniwinther): Provide source information for creation
-              // through synthetic constructors.
-              : null);
-      irBuilder.add(new ir.LetPrim(instance));
-
-      // --- Call constructor bodies ---
-      for (ConstructorElement target in constructorList) {
-        ConstructorBodyElement bodyElement = getConstructorBody(target);
-        if (bodyElement == null) continue; // Skip if constructor has no body.
-        List<ir.Primitive> bodyArguments = <ir.Primitive>[];
-        for (Local param in getConstructorBodyParameters(bodyElement)) {
-          bodyArguments.add(irBuilder.environment.lookup(param));
-        }
-        irBuilder.buildInvokeDirectly(bodyElement, instance, bodyArguments);
-      }
-
-      // --- step 4: return the created object ----
-      irBuilder.buildReturn(
-          value: instance,
-          sourceInformation:
-            sourceInformationBuilder.buildImplicitReturn(constructor));
-
-      return irBuilder.makeFunctionDefinition();
-    });
-  }
-
-  /// Evaluates all field initializers on [constructor] and all constructors
-  /// invoked through `this()` or `super()` ("superconstructors").
-  ///
-  /// The resulting field values will be available in [fieldValues]. The values
-  /// are not stored in any fields.
-  ///
-  /// This procedure assumes that the parameters to [constructor] are available
-  /// in the IR builder's environment.
-  ///
-  /// The parameters to superconstructors are, however, assumed *not* to be in
-  /// the environment, but will be put there by this procedure.
-  ///
-  /// All constructors will be added to [supers], with superconstructors first.
-  void evaluateConstructorFieldInitializers(
-      ConstructorElement constructor,
-      List<ConstructorElement> supers,
-      Map<FieldElement, ir.Primitive> fieldValues) {
-    assert(constructor.isImplementation);
-    assert(constructor == elements.analyzedElement);
-    ClassElement enclosingClass = constructor.enclosingClass.implementation;
-    // Evaluate declaration-site field initializers, unless this constructor
-    // redirects to another using a `this()` initializer. In that case, these
-    // will be initialized by the effective target constructor.
-    if (!constructor.isRedirectingGenerative) {
-      enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) {
-        if (field.initializer != null) {
-          fieldValues[field] = inlineExpression(field, field.initializer);
-        } else {
-          if (backend.isNativeOrExtendsNative(c)) {
-            // Native field is initialized elsewhere.
-          } else {
-            // Fields without an initializer default to null.
-            // This value will be overwritten below if an initializer is found.
-            fieldValues[field] = irBuilder.buildNullConstant();
-          }
-        }
-      });
-    }
-    // If this is a mixin constructor, it does not have its own parameter list
-    // or initializer list. Directly forward to the super constructor.
-    // Note that the declaration-site initializers originating from the
-    // mixed-in class were handled above.
-    if (enclosingClass.isMixinApplication) {
-      forwardSynthesizedMixinConstructor(constructor, supers, fieldValues);
-      return;
-    }
-    // Evaluate initializing parameters, e.g. `Foo(this.x)`.
-    constructor.functionSignature.orderedForEachParameter(
-        (ParameterElement parameter) {
-      if (parameter.isInitializingFormal) {
-        InitializingFormalElement fieldParameter = parameter;
-        fieldValues[fieldParameter.fieldElement] =
-            irBuilder.buildLocalVariableGet(parameter);
-      }
-    });
-    // Evaluate constructor initializers, e.g. `Foo() : x = 50`.
-    ast.FunctionExpression node = constructor.node;
-    bool hasConstructorCall = false; // Has this() or super() initializer?
-    if (node != null && node.initializers != null) {
-      for(ast.Node initializer in node.initializers) {
-        if (initializer is ast.SendSet) {
-          // Field initializer.
-          FieldElement field = elements[initializer];
-          fieldValues[field] = visit(initializer.arguments.head);
-        } else if (initializer is ast.Send) {
-          // Super or this initializer.
-          ConstructorElement target = elements[initializer].implementation;
-          Selector selector = elements.getSelector(initializer);
-          List<ir.Primitive> arguments = initializer.arguments.mapToList(visit);
-          evaluateConstructorCallFromInitializer(
-              target,
-              selector.callStructure,
-              arguments,
-              supers,
-              fieldValues);
-          hasConstructorCall = true;
-        } else {
-          reporter.internalError(initializer,
-                                 "Unexpected initializer type $initializer");
-        }
-      }
-    }
-    // If no super() or this() was found, also call default superconstructor.
-    if (!hasConstructorCall && !enclosingClass.isObject) {
-      ClassElement superClass = enclosingClass.superclass;
-      FunctionElement target = superClass.lookupDefaultConstructor();
-      if (target == null) {
-        reporter.internalError(superClass, "No default constructor available.");
-      }
-      target = target.implementation;
-      evaluateConstructorCallFromInitializer(
-          target,
-          CallStructure.NO_ARGS,
-          const [],
-          supers,
-          fieldValues);
-    }
-    // Add this constructor after the superconstructors.
-    supers.add(constructor);
-  }
-
-  /// Evaluates a call to the given constructor from an initializer list.
-  ///
-  /// Calls [loadArguments] and [evaluateConstructorFieldInitializers] in a
-  /// visitor that has the proper [TreeElements] mapping.
-  void evaluateConstructorCallFromInitializer(
-      ConstructorElement target,
-      CallStructure call,
-      List<ir.Primitive> arguments,
-      List<ConstructorElement> supers,
-      Map<FieldElement, ir.Primitive> fieldValues) {
-    JsIrBuilderVisitor visitor = makeVisitorForContext(target);
-    visitor.withBuilder(irBuilder, () {
-      visitor.loadArguments(target, call, arguments);
-      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
-    });
-  }
-
-  /// Evaluate the implicit super call in the given mixin constructor.
-  void forwardSynthesizedMixinConstructor(
-        ConstructorElement constructor,
-        List<ConstructorElement> supers,
-        Map<FieldElement, ir.Primitive> fieldValues) {
-    assert(constructor.enclosingClass.implementation.isMixinApplication);
-    assert(constructor.isSynthesized);
-    ConstructorElement target =
-        constructor.definingConstructor.implementation;
-    // The resolver gives us the exact same FunctionSignature for the two
-    // constructors. The parameters for the synthesized constructor
-    // are already in the environment, so the target constructor's parameters
-    // are also in the environment since their elements are the same.
-    assert(constructor.functionSignature == target.functionSignature);
-    JsIrBuilderVisitor visitor = makeVisitorForContext(target);
-    visitor.withBuilder(irBuilder, () {
-      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
-    });
-  }
-
-  /// Loads the type variables for all super classes of [superClass] into the
-  /// IR builder's environment with their corresponding values.
-  ///
-  /// The type variables for [currentClass] must already be in the IR builder's
-  /// environment.
-  ///
-  /// Type variables are stored as [TypeVariableLocal] in the environment.
-  ///
-  /// This ensures that access to type variables mentioned inside the
-  /// constructors and initializers will happen through the local environment
-  /// instead of using 'this'.
-  void loadTypeVariablesForSuperClasses(ClassElement currentClass) {
-    if (currentClass.isObject) return;
-    loadTypeVariablesForType(currentClass.supertype);
-    if (currentClass is MixinApplicationElement) {
-      loadTypeVariablesForType(currentClass.mixinType);
-    }
-  }
-
-  /// Loads all type variables for [type] and all of its super classes into
-  /// the environment. All type variables mentioned in [type] must already
-  /// be in the environment.
-  void loadTypeVariablesForType(InterfaceType type) {
-    ClassElement clazz = type.element;
-    assert(clazz.typeVariables.length == type.typeArguments.length);
-    for (int i = 0; i < clazz.typeVariables.length; ++i) {
-      irBuilder.declareTypeVariable(clazz.typeVariables[i],
-                                    type.typeArguments[i]);
-    }
-    loadTypeVariablesForSuperClasses(clazz);
-  }
-
-  /// In preparation of inlining (part of) [target], the [arguments] are moved
-  /// into the environment bindings for the corresponding parameters.
-  ///
-  /// Defaults for optional arguments are evaluated in order to ensure
-  /// all parameters are available in the environment.
-  void loadArguments(ConstructorElement target,
-                     CallStructure call,
-                     List<ir.Primitive> arguments) {
-    assert(target.isImplementation);
-    assert(target == elements.analyzedElement);
-    FunctionSignature signature = target.functionSignature;
-
-    // Establish a scope in case parameters are captured.
-    ClosureScope scope = getClosureScopeForFunction(target);
-    irBuilder.enterScope(scope);
-
-    // Load required parameters
-    int index = 0;
-    signature.forEachRequiredParameter((ParameterElement param) {
-      irBuilder.declareLocalVariable(param, initialValue: arguments[index]);
-      index++;
-    });
-
-    // Load optional parameters, evaluating default values for omitted ones.
-    signature.forEachOptionalParameter((ParameterElement param) {
-      ir.Primitive value;
-      // Load argument if provided.
-      if (signature.optionalParametersAreNamed) {
-        int nameIndex = call.namedArguments.indexOf(param.name);
-        if (nameIndex != -1) {
-          int translatedIndex = call.positionalArgumentCount + nameIndex;
-          value = arguments[translatedIndex];
-        }
-      } else if (index < arguments.length) {
-        value = arguments[index];
-      }
-      // Load default if argument was not provided.
-      if (value == null) {
-        if (param.initializer != null) {
-          value = visit(param.initializer);
-        } else {
-          value = irBuilder.buildNullConstant();
-        }
-      }
-      irBuilder.declareLocalVariable(param, initialValue: value);
-      index++;
-    });
-  }
-
-  /**
-   * Returns the constructor body associated with the given constructor or
-   * creates a new constructor body, if none can be found.
-   *
-   * Returns `null` if the constructor does not have a body.
-   */
-  ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
-    // TODO(asgerf): This is largely inherited from the SSA builder.
-    // The ConstructorBodyElement has an invalid function signature, but we
-    // cannot add a BoxLocal as parameter, because BoxLocal is not an element.
-    // Instead of forging ParameterElements to forge a FunctionSignature, we
-    // need a way to create backend methods without creating more fake elements.
-    assert(constructor.isGenerativeConstructor);
-    assert(constructor.isImplementation);
-    if (constructor.isSynthesized) return null;
-    ast.FunctionExpression node = constructor.node;
-    // If we know the body doesn't have any code, we don't generate it.
-    if (!node.hasBody()) return null;
-    if (node.hasEmptyBody()) return null;
-    ClassElement classElement = constructor.enclosingClass;
-    ConstructorBodyElement bodyElement;
-    classElement.forEachBackendMember((Element backendMember) {
-      if (backendMember.isGenerativeConstructorBody) {
-        ConstructorBodyElement body = backendMember;
-        if (body.constructor == constructor) {
-          bodyElement = backendMember;
-        }
-      }
-    });
-    if (bodyElement == null) {
-      bodyElement = new ConstructorBodyElementX(constructor);
-      classElement.addBackendMember(bodyElement);
-
-      if (constructor.isPatch) {
-        // Create origin body element for patched constructors.
-        ConstructorBodyElementX patch = bodyElement;
-        ConstructorBodyElementX origin =
-            new ConstructorBodyElementX(constructor.origin);
-        origin.applyPatch(patch);
-        classElement.origin.addBackendMember(bodyElement.origin);
-      }
-    }
-    assert(bodyElement.isGenerativeConstructorBody);
-    return bodyElement;
-  }
-
-  /// The list of parameters to send from the generative constructor
-  /// to the generative constructor body.
-  ///
-  /// Boxed parameters are not in the list, instead, a [BoxLocal] is passed
-  /// containing the boxed parameters.
-  ///
-  /// For example, given the following constructor,
-  ///
-  ///     Foo(x, y) : field = (() => ++x) { print(x + y) }
-  ///
-  /// the argument `x` would be replaced by a [BoxLocal]:
-  ///
-  ///     Foo_body(box0, y) { print(box0.x + y) }
-  ///
-  List<Local> getConstructorBodyParameters(ConstructorBodyElement body) {
-    List<Local> parameters = <Local>[];
-    ClosureScope scope = getClosureScopeForFunction(body.constructor);
-    if (scope != null) {
-      parameters.add(scope.box);
-    }
-    body.functionSignature.orderedForEachParameter((ParameterElement param) {
-      if (scope != null && scope.capturedVariables.containsKey(param)) {
-        // Do not pass this parameter; the box will carry its value.
-      } else {
-        parameters.add(param);
-      }
-    });
-    return parameters;
-  }
-
-  TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) {
-    TryBoxedVariables variables = new TryBoxedVariables(elements);
-    try {
-      variables.analyze(node);
-    } catch (e) {
-      bailoutMessage = variables.bailoutMessage;
-      rethrow;
-    }
-    return variables;
-  }
-
-  /// Builds the IR for the body of a constructor.
-  ///
-  /// This function is invoked from one or more "factory" constructors built by
-  /// [buildConstructor].
-  ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) {
-    ConstructorElement constructor = body.constructor;
-    ast.FunctionExpression node = constructor.node;
-    closureClassMap =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            constructor,
-            node,
-            elements);
-
-    // We compute variables boxed in mutable variables on entry to each try
-    // block, not including variables captured by a closure (which are boxed
-    // in the heap).  This duplicates some of the work of closure conversion
-    // without directly using the results.  This duplication is wasteful and
-    // error-prone.
-    // TODO(kmillikin): We should combine closure conversion and try/catch
-    // variable analysis in some way.
-    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
-    tryStatements = variables.tryStatements;
-    IrBuilder builder = getBuilderFor(body);
-
-    return withBuilder(builder, () {
-      irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body),
-                                           getClosureScopeForNode(node));
-      visit(node.body);
-      return irBuilder.makeFunctionDefinition();
-    });
-  }
-
-  ir.FunctionDefinition buildFunction(FunctionElement element) {
-    assert(invariant(element, element.isImplementation));
-    ast.FunctionExpression node = element.node;
-
-    assert(!element.isSynthesized);
-    assert(node != null);
-    assert(elements[node] != null);
-
-    closureClassMap =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            element,
-            node,
-            elements);
-    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
-    tryStatements = variables.tryStatements;
-    IrBuilder builder = getBuilderFor(element);
-    return withBuilder(builder, () => _makeFunctionBody(element, node));
-  }
-
-  /// Creates a primitive for the default value of [parameter].
-  ir.Primitive translateDefaultValue(ParameterElement parameter) {
-    if (parameter.initializer == null) {
-      return irBuilder.buildNullConstant();
-    } else {
-      return inlineConstant(parameter.executableContext, parameter.initializer);
-    }
-  }
-
-  CallStructure normalizeStaticArguments(CallStructure callStructure,
-                                         FunctionElement target,
-                                         List<ir.Primitive> arguments) {
-    target = target.implementation;
-    FunctionSignature signature = target.functionSignature;
-    if (!signature.optionalParametersAreNamed &&
-        signature.parameterCount == arguments.length) {
-      return callStructure;
-    }
-
-    if (!signature.optionalParametersAreNamed) {
-      int i = signature.requiredParameterCount;
-      signature.forEachOptionalParameter((ParameterElement element) {
-        if (i < callStructure.positionalArgumentCount) {
-          ++i;
-        } else {
-          arguments.add(translateDefaultValue(element));
-        }
-      });
-      return new CallStructure(signature.parameterCount);
-    }
-
-    int offset = signature.requiredParameterCount;
-    List<ir.Primitive> namedArguments = arguments.sublist(offset);
-    arguments.length = offset;
-    List<String> normalizedNames = <String>[];
-    // Iterate over the optional parameters of the signature, and try to
-    // find them in the callStructure's named arguments. If found, we use the
-    // value in the temporary list, otherwise the default value.
-    signature.orderedOptionalParameters.forEach((ParameterElement element) {
-      int nameIndex = callStructure.namedArguments.indexOf(element.name);
-      arguments.add(nameIndex == -1 ? translateDefaultValue(element)
-                                    : namedArguments[nameIndex]);
-      normalizedNames.add(element.name);
-    });
-    return new CallStructure(signature.parameterCount, normalizedNames);
-  }
-
-  CallStructure normalizeDynamicArguments(CallStructure callStructure,
-                                          List<ir.Primitive> arguments) {
-    assert(arguments.length == callStructure.argumentCount);
-    if (callStructure.namedArguments.isEmpty) return callStructure;
-    int destinationIndex = callStructure.positionalArgumentCount;
-    List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex);
-    for (String argName in callStructure.getOrderedNamedArguments()) {
-      int sourceIndex = callStructure.namedArguments.indexOf(argName);
-      arguments[destinationIndex++] = namedArguments[sourceIndex];
-    }
-    return new CallStructure(callStructure.argumentCount,
-                             callStructure.getOrderedNamedArguments());
-  }
-
-  @override
-  ir.Primitive handleConstructorInvoke(
-      ast.NewExpression node,
-      ConstructorElement constructor,
-      DartType type,
-      ast.NodeList argumentsNode,
-      CallStructure callStructure,
-      _) {
-    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
-    // Use default values from the effective target, not the immediate target.
-    ConstructorElement target = constructor.effectiveTarget;
-    callStructure =
-        normalizeStaticArguments(callStructure, target, arguments);
-    TypeMask allocationSiteType;
-    ast.Node send = node.send;
-    if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
-        Elements.isGrowableListConstructorCall(constructor, send, compiler) ||
-        Elements.isFilledListConstructorCall(constructor, send, compiler) ||
-        Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) {
-      allocationSiteType = getAllocationSiteType(send);
-    }
-    return irBuilder.buildConstructorInvocation(
-        target,
-        callStructure,
-        constructor.computeEffectiveTargetType(type),
-        arguments,
-        sourceInformationBuilder.buildNew(node),
-        allocationSiteType: allocationSiteType);
-  }
-
-  @override
-  ir.Primitive buildInstanceNoSuchMethod(Selector selector,
-                                         TypeMask mask,
-                                         List<ir.Primitive> arguments) {
-    return irBuilder.buildDynamicInvocation(
-        irBuilder.buildThis(),
-        Selectors.noSuchMethod_,
-        mask,
-        [irBuilder.buildInvocationMirror(selector, arguments)]);
-  }
-
-  @override
-  ir.Primitive buildRuntimeError(String message) {
-    return irBuilder.buildStaticFunctionInvocation(
-        backend.helpers.throwRuntimeError,
-        new CallStructure.unnamed(1),
-        [irBuilder.buildStringConstant(message)]);
-  }
-
-  @override
-  ir.Primitive buildAbstractClassInstantiationError(ClassElement element) {
-    return irBuilder.buildStaticFunctionInvocation(
-        backend.helpers.throwAbstractClassInstantiationError,
-        new CallStructure.unnamed(1),
-        [irBuilder.buildStringConstant(element.name)]);
-  }
-
-  @override
-  ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
-    SourceInformation src = sourceInformationBuilder.buildGet(node);
-    return buildStaticFieldGet(field, src);
-  }
-
-  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
-    ConstantValue constant = getConstantForVariable(field);
-    if (constant != null && !field.isAssignable) {
-      typeMaskSystem.associateConstantValueWithElement(constant, field);
-      return irBuilder.buildConstant(constant, sourceInformation: src);
-    } else if (backend.constants.lazyStatics.contains(field)) {
-      return irBuilder.buildStaticFieldLazyGet(field, src);
-    } else {
-      return irBuilder.buildStaticFieldGet(field, src);
-    }
-  }
-
-  /// Build code to handle foreign code, that is, native JavaScript code, or
-  /// builtin values and operations of the backend.
-  ir.Primitive handleForeignCode(ast.Send node,
-                                 MethodElement function,
-                                 ast.NodeList argumentList,
-                                 CallStructure callStructure) {
-
-    void validateArgumentCount({int minimum, int exactly}) {
-      assert((minimum == null) != (exactly == null));
-      int count = 0;
-      int maximum;
-      if (exactly != null) {
-        minimum = exactly;
-        maximum = exactly;
-      }
-      for (ast.Node argument in argumentList) {
-        count++;
-        if (maximum != null && count > maximum) {
-          internalError(argument, 'Additional argument.');
-        }
-      }
-      if (count < minimum) {
-        internalError(node, 'Expected at least $minimum arguments.');
-      }
-    }
-
-    /// Call a helper method from the isolate library. The isolate library uses
-    /// its own isolate structure, that encapsulates dart2js's isolate.
-    ir.Primitive buildIsolateHelperInvocation(Element element,
-                                              CallStructure callStructure) {
-      if (element == null) {
-        reporter.internalError(node,
-            'Isolate library and compiler mismatch.');
-      }
-      List<ir.Primitive> arguments = <ir.Primitive>[];
-      callStructure = translateStaticArguments(argumentList, element,
-          callStructure, arguments);
-      return irBuilder.buildStaticFunctionInvocation(
-          element,
-          callStructure,
-          arguments,
-          sourceInformation:
-              sourceInformationBuilder.buildCall(node, node.selector));
-    }
-
-    /// Lookup the value of the enum described by [node].
-    getEnumValue(ast.Node node, EnumClassElement enumClass, List values) {
-      Element element = elements[node];
-      if (element is! FieldElement || element.enclosingClass != enumClass) {
-        internalError(node, 'expected a JsBuiltin enum value');
-      }
-
-      int index = enumClass.enumValues.indexOf(element);
-      return values[index];
-    }
-
-    /// Returns the String the node evaluates to, or throws an error if the
-    /// result is not a string constant.
-    String expectStringConstant(ast.Node node) {
-      ir.Primitive nameValue = visit(node);
-      if (nameValue is ir.Constant && nameValue.value.isString) {
-        StringConstantValue constantValue = nameValue.value;
-        return constantValue.primitiveValue.slowToString();
-      } else {
-        return internalError(node, 'expected a literal string');
-      }
-    }
-
-    Link<ast.Node> argumentNodes  = argumentList.nodes;
-    NativeBehavior behavior =
-        compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
-    switch (function.name) {
-      case 'JS':
-        validateArgumentCount(minimum: 2);
-        // The first two arguments are the type and the foreign code template,
-        // which already have been analyzed by the resolver and can be retrieved
-        // using [NativeBehavior]. We can ignore these arguments in the backend.
-        List<ir.Primitive> arguments =
-            argumentNodes.skip(2).mapToList(visit, growable: false);
-        if (behavior.codeTemplate.positionalArgumentCount != arguments.length) {
-          reporter.reportErrorMessage(
-              node, MessageKind.GENERIC,
-              {'text':
-                'Mismatch between number of placeholders'
-                ' and number of arguments.'});
-          return irBuilder.buildNullConstant();
-        }
-
-        if (HasCapturedPlaceholders.check(behavior.codeTemplate.ast)) {
-          reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
-          return irBuilder.buildNullConstant();
-        }
-
-        return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
-            behavior);
-
-      case 'DART_CLOSURE_TO_JS':
-        // TODO(ahe): This should probably take care to wrap the closure in
-        // another closure that saves the current isolate.
-      case 'RAW_DART_FUNCTION_REF':
-        validateArgumentCount(exactly: 1);
-
-        ast.Node argument = node.arguments.single;
-        FunctionElement closure = elements[argument].implementation;
-        if (!Elements.isStaticOrTopLevelFunction(closure)) {
-          internalError(argument,
-              'only static or toplevel function supported');
-        }
-        if (closure.functionSignature.hasOptionalParameters) {
-          internalError(argument,
-              'closures with optional parameters not supported');
-        }
-        return irBuilder.buildForeignCode(
-            js.js.expressionTemplateYielding(
-                backend.emitter.staticFunctionAccess(closure)),
-            <ir.Primitive>[],
-            NativeBehavior.PURE,
-            dependency: closure);
-
-      case 'JS_BUILTIN':
-        // The first argument is a description of the type and effect of the
-        // builtin, which has already been analyzed in the frontend.  The second
-        // argument must be a [JsBuiltin] value.  All other arguments are
-        // values used by the JavaScript template that is associated with the
-        // builtin.
-        validateArgumentCount(minimum: 2);
-
-        ast.Node builtin = argumentNodes.tail.head;
-        JsBuiltin value = getEnumValue(builtin, helpers.jsBuiltinEnum,
-                                       JsBuiltin.values);
-        js.Template template = backend.emitter.builtinTemplateFor(value);
-        List<ir.Primitive> arguments =
-            argumentNodes.skip(2).mapToList(visit, growable: false);
-        return irBuilder.buildForeignCode(template, arguments, behavior);
-
-      case 'JS_EMBEDDED_GLOBAL':
-        validateArgumentCount(exactly: 2);
-
-        String name = expectStringConstant(argumentNodes.tail.head);
-        js.Expression access =
-            backend.emitter.generateEmbeddedGlobalAccess(name);
-        js.Template template = js.js.expressionTemplateYielding(access);
-        return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior);
-
-      case 'JS_INTERCEPTOR_CONSTANT':
-        validateArgumentCount(exactly: 1);
-
-        ast.Node argument = argumentNodes.head;
-        ir.Primitive argumentValue = visit(argument);
-        if (argumentValue is ir.Constant && argumentValue.value.isType) {
-          TypeConstantValue constant = argumentValue.value;
-          ConstantValue interceptorValue =
-              new InterceptorConstantValue(constant.representedType);
-          return irBuilder.buildConstant(interceptorValue);
-        }
-        return internalError(argument, 'expected Type as argument');
-
-      case 'JS_EFFECT':
-        return irBuilder.buildNullConstant();
-
-      case 'JS_GET_NAME':
-        validateArgumentCount(exactly: 1);
-
-        ast.Node argument = argumentNodes.head;
-        JsGetName id = getEnumValue(argument, helpers.jsGetNameEnum,
-            JsGetName.values);
-        js.Name name = backend.namer.getNameForJsGetName(argument, id);
-        ConstantValue nameConstant =
-            new SyntheticConstantValue(SyntheticConstantKind.NAME,
-                                       js.js.quoteName(name));
-
-        return irBuilder.buildConstant(nameConstant);
-
-      case 'JS_GET_FLAG':
-        validateArgumentCount(exactly: 1);
-
-        String name = expectStringConstant(argumentNodes.first);
-        bool value = false;
-        switch (name) {
-          case 'MUST_RETAIN_METADATA':
-            value = backend.mustRetainMetadata;
-            break;
-          case 'USE_CONTENT_SECURITY_POLICY':
-            value = compiler.useContentSecurityPolicy;
-            break;
-          default:
-            internalError(node, 'Unknown internal flag "$name".');
-        }
-        return irBuilder.buildBooleanConstant(value);
-
-      case 'JS_STRING_CONCAT':
-        validateArgumentCount(exactly: 2);
-        List<ir.Primitive> arguments = argumentNodes.mapToList(visit);
-        return irBuilder.buildStringConcatenation(arguments);
-
-      case 'JS_CURRENT_ISOLATE_CONTEXT':
-        validateArgumentCount(exactly: 0);
-
-        if (!compiler.hasIsolateSupport) {
-          // If the isolate library is not used, we just generate code
-          // to fetch the current isolate.
-          continue getStaticState;
-        }
-        return buildIsolateHelperInvocation(backend.helpers.currentIsolate,
-            CallStructure.NO_ARGS);
-
-      getStaticState: case 'JS_GET_STATIC_STATE':
-        validateArgumentCount(exactly: 0);
-
-        return irBuilder.buildForeignCode(
-            js.js.parseForeignJS(backend.namer.staticStateHolder),
-            const <ir.Primitive>[],
-            NativeBehavior.PURE);
-
-      case 'JS_SET_STATIC_STATE':
-        validateArgumentCount(exactly: 1);
-
-        ir.Primitive value = visit(argumentNodes.single);
-        String isolateName = backend.namer.staticStateHolder;
-        return irBuilder.buildForeignCode(
-            js.js.parseForeignJS("$isolateName = #"),
-            <ir.Primitive>[value],
-            NativeBehavior.PURE);
-
-      case 'JS_CALL_IN_ISOLATE':
-        validateArgumentCount(exactly: 2);
-
-        if (!compiler.hasIsolateSupport) {
-          ir.Primitive closure = visit(argumentNodes.tail.head);
-          return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
-              const <ir.Primitive>[]);
-        }
-        return buildIsolateHelperInvocation(backend.helpers.callInIsolate,
-            CallStructure.TWO_ARGS);
-
-      default:
-        return giveup(node, 'unplemented native construct: ${function.name}');
-    }
-  }
-
-  @override
-  ir.Primitive handleStaticFunctionInvoke(ast.Send node,
-                                          MethodElement function,
-                                          ast.NodeList argumentsNode,
-                                          CallStructure callStructure,
-                                          _) {
-    if (compiler.backend.isForeign(function)) {
-      return handleForeignCode(node, function, argumentsNode, callStructure);
-    } else {
-      List<ir.Primitive> arguments = <ir.Primitive>[];
-      callStructure = translateStaticArguments(argumentsNode, function,
-          callStructure, arguments);
-      return irBuilder.buildStaticFunctionInvocation(function,
-          callStructure,
-          arguments,
-          sourceInformation:
-              sourceInformationBuilder.buildCall(node, node.selector));
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index e34a4a4..49c8a6b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -18,7 +18,7 @@
 // These imports are only used for the JavaScript specific nodes.  If we want to
 // support more than one native backend, we should probably create better
 // abstractions for native code and its type and effect system.
-import '../js/js.dart' as js show Template;
+import '../js/js.dart' as js show Template, isNullGuardOnFirstArgument;
 import '../native/native.dart' as native show NativeBehavior;
 
 abstract class Node {
@@ -64,6 +64,8 @@
   /// For [InteriorExpression]s this is the body, for [CallExpressions] it is
   /// the body of the continuation, and for [TailExpressions] it is `null`.
   Expression get next;
+
+  accept(BlockVisitor visitor);
 }
 
 /// Represents a node with a child node, which can be accessed through the
@@ -77,6 +79,8 @@
 abstract class InteriorNode extends Node {
   Expression get body;
   void set body(Expression body);
+
+  accept(BlockVisitor visitor);
 }
 
 /// An expression that creates new bindings and continues evaluation in
@@ -370,7 +374,7 @@
     return body = expr;
   }
 
-  accept(Visitor visitor) => visitor.visitLetPrim(this);
+  accept(BlockVisitor visitor) => visitor.visitLetPrim(this);
 
   void setParentPointers() {
     primitive.parent = this;
@@ -410,7 +414,7 @@
     return continuations.first.body = expr;
   }
 
-  accept(Visitor visitor) => visitor.visitLetCont(this);
+  accept(BlockVisitor visitor) => visitor.visitLetCont(this);
 
   void setParentPointers() {
     _setParentsOnNodes(continuations, this);
@@ -433,7 +437,7 @@
 
   LetHandler(this.handler, this.body);
 
-  accept(Visitor visitor) => visitor.visitLetHandler(this);
+  accept(BlockVisitor visitor) => visitor.visitLetHandler(this);
 
   void setParentPointers() {
     handler.parent = this;
@@ -462,7 +466,7 @@
     return body = expr;
   }
 
-  accept(Visitor visitor) => visitor.visitLetMutable(this);
+  accept(BlockVisitor visitor) => visitor.visitLetMutable(this);
 
   void setParentPointers() {
     variable.parent = this;
@@ -505,7 +509,28 @@
   SourceInformation get sourceInformation;
 
   Reference<Primitive> get dartReceiverReference => null;
+  Primitive get dartReceiver => dartReceiverReference.definition;
+
   CallingConvention get callingConvention => CallingConvention.Normal;
+
+  Reference<Primitive> dartArgumentReference(int n) {
+    switch (callingConvention) {
+      case CallingConvention.Normal:
+      case CallingConvention.OneShotIntercepted:
+        return arguments[n];
+
+      case CallingConvention.Intercepted:
+      case CallingConvention.DummyIntercepted:
+        return arguments[n + 1];
+    }
+  }
+
+  Primitive dartArgument(int n) => dartArgumentReference(n).definition;
+
+  int get dartArgumentsLength =>
+      arguments.length -
+      (callingConvention == CallingConvention.Intercepted ||
+          callingConvention == CallingConvention.DummyIntercepted ? 1 : 0);
 }
 
 /// Invoke a static function.
@@ -566,22 +591,6 @@
         : receiver;
   }
 
-  Primitive get dartReceiver => dartReceiverReference.definition;
-
-  Reference<Primitive> dartArgumentReference(int n) {
-    switch (callingConvention) {
-      case CallingConvention.Normal:
-      case CallingConvention.OneShotIntercepted:
-        return arguments[n];
-
-      case CallingConvention.Intercepted:
-      case CallingConvention.DummyIntercepted:
-        return arguments[n + 1];
-    }
-  }
-
-  Primitive dartArgument(int n) => dartArgumentReference(n).definition;
-
   /// If true, it is known that the receiver cannot be `null`.
   bool receiverIsNotNull = false;
 
@@ -589,16 +598,11 @@
                this.selector,
                this.mask,
                List<Primitive> arguments,
-               [this.sourceInformation])
+               {this.sourceInformation,
+                this.callingConvention: CallingConvention.Normal})
       : this.receiver = new Reference<Primitive>(receiver),
         this.arguments = _referenceList(arguments);
 
-  InvokeMethod.byReference(this.receiver,
-                           this.selector,
-                           this.mask,
-                           this.arguments,
-                           this.sourceInformation);
-
   accept(Visitor visitor) => visitor.visitInvokeMethod(this);
 
   bool get hasValue => true;
@@ -635,7 +639,7 @@
   final List<Reference<Primitive>> arguments;
   final SourceInformation sourceInformation;
 
-  CallingConvention callingConvention = CallingConvention.Normal;
+  CallingConvention callingConvention;
 
   Reference<Primitive> get dartReceiverReference {
     return callingConvention == CallingConvention.Intercepted
@@ -643,21 +647,12 @@
         : receiver;
   }
 
-  Primitive get dartReceiver => dartReceiverReference.definition;
-
-  Reference<Primitive> dartArgumentReference(int n) {
-    return callingConvention == CallingConvention.Normal
-        ? arguments[n]
-        : arguments[n + 1];
-  }
-
-  Primitive dartArgument(int n) => dartArgumentReference(n).definition;
-
   InvokeMethodDirectly(Primitive receiver,
                        this.target,
                        this.selector,
                        List<Primitive> arguments,
-                       this.sourceInformation)
+                       this.sourceInformation,
+                       {this.callingConvention: CallingConvention.Normal})
       : this.receiver = new Reference<Primitive>(receiver),
         this.arguments = _referenceList(arguments);
 
@@ -732,7 +727,7 @@
     : value = new Reference<Primitive>(value);
 
   bool get hasValue => true;
-  bool get isSafeForElimination => true;
+  bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
   accept(Visitor visitor) => visitor.visitRefinement(this);
@@ -805,7 +800,7 @@
       [this.checks = BOTH_BOUNDS, this.sourceInformation])
       : this.object = new Reference<Primitive>(object),
         this.index = new Reference<Primitive>(index),
-        this.length = new Reference<Primitive>(length);
+        this.length = length == null ? null : new Reference<Primitive>(length);
 
   BoundsCheck.noCheck(Primitive object, [this.sourceInformation])
       : this.object = new Reference<Primitive>(object),
@@ -850,10 +845,13 @@
 ///
 /// In the simplest form this compiles to `value.toString;`.
 ///
-/// If [selector] is set, `toString` is replaced with the (possibly minified)
-/// invocation name of the selector.  This can be shorter and generate a more
-/// meaningful error message, but is expensive if [value] is non-null and does
-/// not have that property at runtime.
+/// [selector] holds the selector that is the cause of the null check. This is
+/// usually a method that was inlined where [value] the receiver.
+///
+/// If [selector] is set and [useSelector] is true, `toString` is replaced with
+/// the (possibly minified) invocation name of the selector.  This can be
+/// shorter and generate a more meaningful error message, but is expensive if
+/// [value] is non-null and does not have that property at runtime.
 ///
 /// If [condition] is set, it is assumed that [condition] is true if and only
 /// if [value] is null.  The check then compiles to:
@@ -864,17 +862,24 @@
 /// runtime, such as a `typeof` test.
 class NullCheck extends Primitive {
   final Reference<Primitive> value;
-  Selector selector;
-  Reference<Primitive> condition;
+  final Selector selector;
+  final bool useSelector;
+  final Reference<Primitive> condition;
   final SourceInformation sourceInformation;
 
-  NullCheck(Primitive value, this.sourceInformation)
-      : this.value = new Reference<Primitive>(value);
+  NullCheck(Primitive value, this.sourceInformation,
+            {Primitive condition,
+             this.selector,
+             this.useSelector: false})
+      : this.value = new Reference<Primitive>(value),
+        this.condition =
+            condition == null ? null : new Reference<Primitive>(condition);
 
   NullCheck.guarded(Primitive condition, Primitive value, this.selector,
         this.sourceInformation)
       : this.condition = new Reference<Primitive>(condition),
-        this.value = new Reference<Primitive>(value);
+        this.value = new Reference<Primitive>(value),
+        this.useSelector = true;
 
   bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
@@ -1052,7 +1057,7 @@
 
   Throw(Primitive value) : value = new Reference<Primitive>(value);
 
-  accept(Visitor visitor) => visitor.visitThrow(this);
+  accept(BlockVisitor visitor) => visitor.visitThrow(this);
 
   void setParentPointers() {
     value.parent = this;
@@ -1065,7 +1070,7 @@
 /// implicitly throws the exception parameter of the enclosing handler with
 /// the same stack trace as the enclosing handler.
 class Rethrow extends TailExpression {
-  accept(Visitor visitor) => visitor.visitRethrow(this);
+  accept(BlockVisitor visitor) => visitor.visitRethrow(this);
   void setParentPointers() {}
 }
 
@@ -1074,7 +1079,7 @@
 /// This can be placed as the body of a call continuation, when the caller is
 /// known never to invoke it, e.g. because the calling expression always throws.
 class Unreachable extends TailExpression {
-  accept(Visitor visitor) => visitor.visitUnreachable(this);
+  accept(BlockVisitor visitor) => visitor.visitUnreachable(this);
   void setParentPointers() {}
 }
 
@@ -1163,7 +1168,7 @@
         arguments = null,
         sourceInformation = null;
 
-  accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
+  accept(BlockVisitor visitor) => visitor.visitInvokeContinuation(this);
 
   void setParentPointers() {
     if (continuation != null) continuation.parent = this;
@@ -1186,23 +1191,28 @@
   /// boolean.
   bool isStrictCheck;
 
-  Branch.strict(Primitive condition,
-                Continuation trueCont,
-                Continuation falseCont)
+  Branch(Primitive condition,
+         Continuation trueCont,
+         Continuation falseCont,
+         {bool strict})
       : this.condition = new Reference<Primitive>(condition),
         trueContinuation = new Reference<Continuation>(trueCont),
         falseContinuation = new Reference<Continuation>(falseCont),
-        isStrictCheck = true;
+        isStrictCheck = strict {
+    assert(strict != null);
+  }
+
+  Branch.strict(Primitive condition,
+                Continuation trueCont,
+                Continuation falseCont)
+        : this(condition, trueCont, falseCont, strict: true);
 
   Branch.loose(Primitive condition,
                Continuation trueCont,
                Continuation falseCont)
-      : this.condition = new Reference<Primitive>(condition),
-        trueContinuation = new Reference<Continuation>(trueCont),
-        falseContinuation = new Reference<Continuation>(falseCont),
-        this.isStrictCheck = false;
+      : this(condition, trueCont, falseCont, strict: false);
 
-  accept(Visitor visitor) => visitor.visitBranch(this);
+  accept(BlockVisitor visitor) => visitor.visitBranch(this);
 
   void setParentPointers() {
     condition.parent = this;
@@ -1484,62 +1494,6 @@
   final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
   final SourceInformation sourceInformation;
 
-  /// The input was a self-interceptor.
-  static const int SELF_INTERCEPT = 1 << 0;
-
-  /// A non-null value was mapped to an interceptor that was mentioned in
-  /// [interceptedClasses].
-  static const int NON_NULL_INTERCEPT_EXACT = 1 << 1;
-
-  /// A non-null value was mapped to an interceptor that is a subclass of
-  /// one mentioned in [interceptedClasses].
-  static const int NON_NULL_INTERCEPT_SUBCLASS = 1 << 2;
-
-  /// A non-null intercepted value was bypassed because none of its supertypes
-  /// were mentioned in [interceptedClasses].
-  static const int NON_NULL_BYPASS = 1 << 3;
-
-  /// Null was returned as-is.
-  static const int NULL_BYPASS = 1 << 4;
-
-  /// Null was mapped to JSNull, which was mentioned in [interceptedClasses].
-  static const int NULL_INTERCEPT_EXACT = 1 << 5;
-
-  /// Null was mapped to JSNull, because a superclass thereof (the interceptor
-  /// root class) was mentioned in [interceptedClasses].
-  static const int NULL_INTERCEPT_SUBCLASS = 1 << 6;
-
-  static const int NON_NULL_INTERCEPT = NON_NULL_INTERCEPT_EXACT |
-                                        NON_NULL_INTERCEPT_SUBCLASS;
-  static const int NULL_INTERCEPT = NULL_INTERCEPT_EXACT |
-                                    NULL_INTERCEPT_SUBCLASS;
-  static const int NULL = NULL_BYPASS |
-                          NULL_INTERCEPT;
-  static const int INTERCEPT_EXACT = NON_NULL_INTERCEPT_EXACT |
-                                     NULL_INTERCEPT_EXACT;
-  static const int INTERCEPT_SUBCLASS = NON_NULL_INTERCEPT_SUBCLASS |
-                                        NULL_INTERCEPT_SUBCLASS;
-  static const int INTERCEPT = NULL_INTERCEPT | NON_NULL_INTERCEPT;
-  static const int BYPASS = NULL_BYPASS | NON_NULL_BYPASS;
-
-  static const int ALL_FLAGS = SELF_INTERCEPT | BYPASS | INTERCEPT;
-
-  /// Which of the above cases may happen at runtime. Set by type propagation.
-  int flags = ALL_FLAGS;
-
-  void clearFlag(int flag) {
-    flags &= ~flag;
-  }
-
-  bool get isAlwaysIntercepted => flags & ~INTERCEPT == 0;
-  bool get isAlwaysNullOrIntercepted => flags & ~(NULL | INTERCEPT) == 0;
-
-  /// If the value is intercepted, it always matches exactly a class in
-  /// [interceptedClasses].
-  bool get isInterceptedClassAlwaysExact {
-    return flags & (INTERCEPT & ~INTERCEPT_EXACT) == 0;
-  }
-
   Interceptor(Primitive input, this.sourceInformation)
       : this.input = new Reference<Primitive>(input);
 
@@ -1591,6 +1545,15 @@
   void setParentPointers() {
     _setParentsOnList(arguments, this);
   }
+
+  bool isNullGuardOnNullFirstArgument() {
+    if (arguments.length < 1) return false;
+    // TODO(sra): Fix NativeThrowBehavior to distinguish MAY from
+    // throws-nsm-on-null-followed-by-MAY and remove
+    // [isNullGuardForFirstArgument].
+    if (nativeBehavior.throwBehavior.isNullNSMGuard) return true;
+    return js.isNullGuardOnFirstArgument(codeTemplate);
+  }
 }
 
 class Constant extends Primitive {
@@ -1696,7 +1659,7 @@
     : parameters = <Parameter>[new Parameter(null)],
       isRecursive = false;
 
-  accept(Visitor visitor) => visitor.visitContinuation(this);
+  accept(BlockVisitor visitor) => visitor.visitContinuation(this);
 
   void setParentPointers() {
     _setParentsOnNodes(parameters, this);
@@ -1751,7 +1714,7 @@
       this.returnContinuation,
       this.body);
 
-  accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
+  accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this);
 
   void setParentPointers() {
     if (thisParameter != null) thisParameter.parent = this;
@@ -1893,25 +1856,102 @@
   }
 }
 
-abstract class Visitor<T> {
+/// Visitor for block-level traversals that do not need to dispatch on
+/// primitives.
+abstract class BlockVisitor<T> {
+  const BlockVisitor();
+
+  T visit(Node node) => node.accept(this);
+
+  // Block headers.
+  T visitFunctionDefinition(FunctionDefinition node) => null;
+  T visitContinuation(Continuation node) => null;
+
+  // Interior expressions.
+  T visitLetPrim(LetPrim node) => null;
+  T visitLetCont(LetCont node) => null;
+  T visitLetHandler(LetHandler node) => null;
+  T visitLetMutable(LetMutable node) => null;
+
+  // Tail expressions.
+  T visitInvokeContinuation(InvokeContinuation node) => null;
+  T visitThrow(Throw node) => null;
+  T visitRethrow(Rethrow node) => null;
+  T visitBranch(Branch node) => null;
+  T visitUnreachable(Unreachable node) => null;
+
+  /// Visits block-level nodes in lexical post-order (not post-dominator order).
+  ///
+  /// Continuations and function definitions are considered "block headers".
+  /// The block itself is the sequence of interior expressions in the body,
+  /// terminated by a tail expression.
+  ///
+  /// Each block is visited starting with its tail expression, then every
+  /// interior expression from bottom to top, and finally the block header
+  /// is visited.
+  ///
+  /// Blocks are visited in post-order, so the body of a continuation is always
+  /// processed before its non-recursive invocation sites.
+  ///
+  /// The IR may be transformed during the traversal, but only the original
+  /// nodes will be visited.
+  static void traverseInPostOrder(FunctionDefinition root, BlockVisitor v) {
+    List<Continuation> stack = <Continuation>[];
+    List<Node> nodes = <Node>[];
+    void walkBlock(InteriorNode block) {
+      nodes.add(block);
+      Expression node = block.body;
+      nodes.add(node);
+      while (node.next != null) {
+        if (node is LetCont) {
+          stack.addAll(node.continuations);
+        } else if (node is LetHandler) {
+          stack.add(node.handler);
+        }
+        node = node.next;
+        nodes.add(node);
+      }
+    }
+    walkBlock(root);
+    while (stack.isNotEmpty) {
+      walkBlock(stack.removeLast());
+    }
+    nodes.reversed.forEach(v.visit);
+  }
+
+  /// Visits block-level nodes in lexical pre-order.
+  ///
+  /// The IR may be transformed during the traversal, but the currently
+  /// visited node should not be removed, as its 'body' pointer is needed
+  /// for the traversal.
+  static void traverseInPreOrder(FunctionDefinition root, BlockVisitor v) {
+    List<Continuation> stack = <Continuation>[];
+    void walkBlock(InteriorNode block) {
+      v.visit(block);
+      Expression node = block.body;
+      v.visit(node);
+      while (node.next != null) {
+        if (node is LetCont) {
+          stack.addAll(node.continuations);
+        } else if (node is LetHandler) {
+          stack.add(node.handler);
+        }
+        node = node.next;
+        v.visit(node);
+      }
+    }
+    walkBlock(root);
+    while (stack.isNotEmpty) {
+      walkBlock(stack.removeLast());
+    }
+  }
+}
+
+abstract class Visitor<T> implements BlockVisitor<T> {
   const Visitor();
 
   T visit(Node node);
 
-  // Concrete classes.
-  T visitFunctionDefinition(FunctionDefinition node);
-
-  // Expressions.
-  T visitLetPrim(LetPrim node);
-  T visitLetCont(LetCont node);
-  T visitLetHandler(LetHandler node);
-  T visitLetMutable(LetMutable node);
-  T visitInvokeContinuation(InvokeContinuation node);
-  T visitThrow(Throw node);
-  T visitRethrow(Rethrow node);
-  T visitBranch(Branch node);
-  T visitUnreachable(Unreachable node);
-
   // Definitions.
   T visitInvokeStatic(InvokeStatic node);
   T visitInvokeMethod(InvokeMethod node);
@@ -1929,7 +1969,6 @@
   T visitConstant(Constant node);
   T visitGetMutable(GetMutable node);
   T visitParameter(Parameter node);
-  T visitContinuation(Continuation node);
   T visitMutableVariable(MutableVariable node);
   T visitGetStatic(GetStatic node);
   T visitInterceptor(Interceptor node);
@@ -1950,8 +1989,6 @@
   T visitRefinement(Refinement node);
   T visitBoundsCheck(BoundsCheck node);
   T visitNullCheck(NullCheck node);
-
-  // Support for literal foreign code.
   T visitForeignCode(ForeignCode node);
 }
 
@@ -2483,20 +2520,23 @@
   Definition visitInvokeMethod(InvokeMethod node) {
     return new InvokeMethod(getCopy(node.receiver), node.selector, node.mask,
         getList(node.arguments),
-        node.sourceInformation);
+        sourceInformation: node.sourceInformation,
+        callingConvention: node.callingConvention);
   }
 
   Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) {
     return new InvokeMethodDirectly(getCopy(node.receiver), node.target,
         node.selector,
         getList(node.arguments),
-        node.sourceInformation);
+        node.sourceInformation,
+        callingConvention: node.callingConvention);
   }
 
   Definition visitInvokeConstructor(InvokeConstructor node) {
     return new InvokeConstructor(node.dartType, node.target, node.selector,
         getList(node.arguments),
-        node.sourceInformation);
+        node.sourceInformation)
+        ..allocationSiteType = node.allocationSiteType;
   }
 
   Definition visitTypeCast(TypeCast node) {
@@ -2530,7 +2570,8 @@
   }
 
   Definition visitLiteralList(LiteralList node) {
-    return new LiteralList(node.dartType, getList(node.values));
+    return new LiteralList(node.dartType, getList(node.values))
+        ..allocationSiteType = node.allocationSiteType;
   }
 
   Definition visitLiteralMap(LiteralMap node) {
@@ -2640,14 +2681,17 @@
           node.sourceInformation);
     } else {
       return new BoundsCheck(getCopy(node.object), getCopy(node.index),
-          getCopy(node.length),
+          node.length == null ? null : getCopy(node.length),
           node.checks,
           node.sourceInformation);
     }
   }
 
   Definition visitNullCheck(NullCheck node) {
-    return new NullCheck(getCopy(node.value), node.sourceInformation);
+    return new NullCheck(getCopy(node.value), node.sourceInformation,
+        condition: node.condition == null ? null : getCopy(node.condition),
+        selector: node.selector,
+        useSelector: node.useSelector);
   }
 
   Definition visitForeignCode(ForeignCode node) {
diff --git a/pkg/compiler/lib/src/cps_ir/gvn.dart b/pkg/compiler/lib/src/cps_ir/gvn.dart
index cb84402..a4a591f 100644
--- a/pkg/compiler/lib/src/cps_ir/gvn.dart
+++ b/pkg/compiler/lib/src/cps_ir/gvn.dart
@@ -64,10 +64,6 @@
   final Map<Primitive, Continuation> loopHeaderFor =
       <Primitive, Continuation>{};
 
-  /// The loop to which a given trivial primitive can be hoisted.
-  final Map<Primitive, Continuation> potentialLoopHeaderFor =
-      <Primitive, Continuation>{};
-
   /// The GVNs for primitives that have been hoisted outside the given loop.
   ///
   /// These should be removed from the environment when exiting the loop.
@@ -155,11 +151,10 @@
     Primitive existing = environment[gvn];
     if (existing != null &&
         canReplaceWithExistingValue(prim) &&
-        !isTrivialPrimitive(prim)) {
+        !isFastConstant(prim)) {
       if (prim is Interceptor) {
         Interceptor interceptor = existing;
         interceptor.interceptedClasses.addAll(prim.interceptedClasses);
-        interceptor.flags |= prim.flags;
       }
       prim..replaceUsesWith(existing)..destroy();
       node.remove();
@@ -181,15 +176,48 @@
     return next;
   }
 
+  bool isFirstImpureExpressionInLoop(Expression exp) {
+    InteriorNode node = exp.parent;
+    for (; node is Expression; node = node.parent) {
+      if (node is LetPrim && node.primitive.isSafeForElimination) {
+        continue;
+      }
+      if (node is LetCont) {
+        continue;
+      }
+      return false;
+    }
+    return node == currentLoopHeader;
+  }
+
+  bool isHoistablePrimitive(Primitive prim) {
+    if (prim.isSafeForElimination) return true;
+    if (prim is NullCheck ||
+        prim is BoundsCheck ||
+        prim is GetLength ||
+        prim is GetField ||
+        prim is GetIndex) {
+      // Expressions that potentially throw but have no other effects can be
+      // hoisted if they occur as the first impure expression in a loop.
+      // Note regarding BoundsCheck: the current array length is an input to
+      // check, so the check itself has no heap dependency.  It will only be
+      // hoisted if the length was hoisted.
+      // TODO(asgerf): In general we could hoist these out of multiple loops,
+      //   but the trick we use here only works for one loop level.
+      return isFirstImpureExpressionInLoop(prim.parent);
+    }
+    return false;
+  }
+
   /// Try to hoist the binding of [prim] out of loops. Returns `true` if it was
   /// hoisted or marked as a trivial hoist-on-demand primitive.
   bool tryToHoistOutOfLoop(Primitive prim, int gvn) {
-    // Do not hoist primitives with side effects.
-    if (!prim.isSafeForElimination) return false;
-
     // Bail out fast if the primitive is not inside a loop.
     if (currentLoopHeader == null) return false;
 
+    // Do not hoist primitives with side effects.
+    if (!isHoistablePrimitive(prim)) return false;
+
     LetPrim letPrim = prim.parent;
 
     // Find the depth of the outermost scope where we can bind the primitive
@@ -202,21 +230,18 @@
       if (canIgnoreRefinementGuards(prim)) {
         input = input.effectiveDefinition;
       }
-      Continuation loopHeader;
-      if (potentialLoopHeaderFor.containsKey(input)) {
-        // This is a reference to a value that can be hoisted further out than
-        // it currently is.  If we decide to hoist [prim], we must also hoist
-        // such dependent values.
-        loopHeader = potentialLoopHeaderFor[input];
+      if (isFastConstant(input)) {
+        // Fast constants can be hoisted all the way out, but should only be
+        // hoisted if needed to hoist something else.
         inputsHoistedOnDemand.add(input);
       } else {
-        loopHeader = loopHeaderFor[input];
-      }
-      Continuation referencedLoop =
-          loopHierarchy.lowestCommonAncestor(loopHeader, currentLoopHeader);
-      int depth = loopHierarchy.getDepth(referencedLoop);
-      if (depth > hoistDepth) {
-        hoistDepth = depth;
+        Continuation loopHeader = loopHeaderFor[input];
+        Continuation referencedLoop =
+            loopHierarchy.lowestCommonAncestor(loopHeader, currentLoopHeader);
+        int depth = loopHierarchy.getDepth(referencedLoop);
+        if (depth > hoistDepth) {
+          hoistDepth = depth;
+        }
       }
     });
 
@@ -236,11 +261,10 @@
     // Bail out if heap dependencies prohibit any hoisting at all.
     if (hoistTarget == null) return false;
 
-    if (isTrivialPrimitive(prim)) {
+    if (isFastConstant(prim)) {
       // The overhead from introducting a temporary might be greater than
       // the overhead of evaluating this primitive at every iteration.
       // Only hoist if this enables hoisting of a non-trivial primitive.
-      potentialLoopHeaderFor[prim] = enclosingLoop;
       return true;
     }
 
@@ -287,8 +311,7 @@
   void hoistTrivialPrimitive(Primitive prim,
                              LetCont loopBinding,
                              Continuation enclosingLoop) {
-    if (!potentialLoopHeaderFor.containsKey(prim)) return;
-    assert(isTrivialPrimitive(prim));
+    assert(isFastConstant(prim));
 
     // The primitive might already be bound in an outer scope.  Do not relocate
     // the primitive unless we are lifting it. For example;
@@ -313,26 +336,15 @@
     binding.remove();
     binding.insertAbove(loopBinding);
     loopHeaderFor[prim] = enclosingLoop;
-
-    if (potentialLoopHeaderFor[prim] == enclosingLoop) {
-      potentialLoopHeaderFor.remove(prim);
-    }
   }
 
   bool canIgnoreRefinementGuards(Primitive primitive) {
     return primitive is Interceptor;
   }
 
-  /// Returns true if the given primitive is so cheap at runtime that it is
-  /// better to (redundantly) recompute it rather than introduce a temporary.
-  bool isTrivialPrimitive(Primitive primitive) {
-    return primitive is ApplyBuiltinOperator ||
-           primitive is Constant && isTrivialConstant(primitive.value);
-  }
-
-  /// Returns true if the given constant has almost no runtime cost.
-  bool isTrivialConstant(ConstantValue value) {
-    return value.isPrimitive || value.isDummy;
+  /// Returns true if [prim] is a constant that has no significant runtime cost.
+  bool isFastConstant(Primitive prim) {
+    return prim is Constant && (prim.value.isPrimitive || prim.value.isDummy);
   }
 
   /// True if [element] is a final or constant field or a function.
@@ -348,9 +360,15 @@
   }
 
   /// Assuming [prim] has no side effects, returns true if it can safely
-  /// be hoisted out of [loop] without changing its value.
+  /// be hoisted out of [loop] without changing its value or changing the timing
+  /// of a thrown exception.
   bool canHoistHeapDependencyOutOfLoop(Primitive prim, Continuation loop) {
-    assert(prim.isSafeForElimination);
+    // If the primitive might throw, we have to check that it is the first
+    // impure expression in the loop.  This has already been checked if
+    // [loop] is the current loop header, but for other loops we just give up.
+    if (!prim.isSafeForElimination && loop != currentLoopHeader) {
+      return false;
+    }
     if (prim is GetLength && !isImmutableLength(prim)) {
       return !loopEffects.loopChangesLength(loop);
     } else if (prim is GetField && !isImmutable(prim.field)) {
@@ -364,7 +382,6 @@
     }
   }
 
-
   // ------------------ TRAVERSAL AND EFFECT NUMBERING ---------------------
   //
   // These methods traverse the IR while updating the current effect numbers.
diff --git a/pkg/compiler/lib/src/cps_ir/inline.dart b/pkg/compiler/lib/src/cps_ir/inline.dart
index d3d2672..cc046ee 100644
--- a/pkg/compiler/lib/src/cps_ir/inline.dart
+++ b/pkg/compiler/lib/src/cps_ir/inline.dart
@@ -163,7 +163,7 @@
   }
 
   void rewrite(FunctionDefinition node, [CallStructure callStructure]) {
-    Element function = node.element;
+    ExecutableElement function = node.element;
 
     // Inlining in asynchronous or generator functions is disabled.  Inlining
     // triggers a bug in the async rewriter.
@@ -174,6 +174,13 @@
       return;
     }
 
+    // Do not inline in functions containing try statements.  V8 does not
+    // optimize code in such functions, so inlining will move optimizable code
+    // into a context where it cannot be optimized.
+    if (function.resolvedAst.elements.containsTryStatement) {
+      return;
+    }
+
     stack.add(new StackEntry(function, callStructure));
     new InliningVisitor(this).visit(node);
     assert(stack.last.match(function, callStructure));
@@ -213,7 +220,11 @@
   // Inlining a function incurs a cost equal to the number of primitives and
   // non-jump tail expressions.
   // TODO(kmillikin): Tune the size computation and size bound.
-  processLetPrim(LetPrim node) => ++size;
+  processLetPrim(LetPrim node) {
+    if (node.primitive is! Refinement) {
+      ++size;
+    }
+  }
   processLetMutable(LetMutable node) => ++size;
   processBranch(Branch node) => ++size;
   processThrow(Throw nose) => ++size;
@@ -350,25 +361,37 @@
   Primitive tryInlining(InvocationPrimitive invoke, FunctionElement target,
                         CallStructure callStructure) {
     // Quick checks: do not inline or even cache calls to targets without an
-    // AST node or targets that are asynchronous or generator functions.
+    // AST node, targets that are asynchronous or generator functions, or
+    // targets containing a try statement.
     if (!target.hasNode) return null;
     if (target.asyncMarker != AsyncMarker.SYNC) return null;
+    // V8 does not optimize functions containing a try statement.  Inlining
+    // code containing a try statement will make the optimizable calling code
+    // become unoptimizable.
+    if (target.resolvedAst.elements.containsTryStatement) {
+      return null;
+    }
 
     Reference<Primitive> dartReceiver = invoke.dartReceiverReference;
     TypeMask abstractReceiver =
         dartReceiver == null ? null : abstractType(dartReceiver);
+    // The receiver is non-null in a method body, unless the receiver is known
+    // to be `null` (isEmpty covers `null` and unreachable).
+    TypeMask abstractReceiverInMethod = abstractReceiver == null
+        ? null
+        : abstractReceiver.isEmpty
+            ? abstractReceiver
+            : abstractReceiver.nonNullable();
     List<TypeMask> abstractArguments =
         invoke.arguments.map(abstractType).toList();
     var cachedResult = _inliner.cache.get(target, callStructure,
-        abstractReceiver,
+        abstractReceiverInMethod,
         abstractArguments);
 
     // Negative inlining result in the cache.
     if (cachedResult == InliningCache.NO_INLINE) return null;
 
-    // Positive inlining result in the cache.
-    if (cachedResult is FunctionDefinition) {
-      FunctionDefinition function = cachedResult;
+    Primitive finish(FunctionDefinition function) {
       _fragment = new CpsFragment(invoke.sourceInformation);
       Primitive receiver = invoke.receiver?.definition;
       List<Primitive> arguments =
@@ -388,12 +411,17 @@
           hint: invoke.hint);
     }
 
+    // Positive inlining result in the cache.
+    if (cachedResult is FunctionDefinition) {
+      return finish(cachedResult);
+    }
+
     // We have not seen this combination of target and abstract arguments
     // before.  Make an inlining decision.
     assert(cachedResult == InliningCache.ABSENT);
     Primitive doNotInline() {
-      _inliner.cache.putNegative(target, callStructure, abstractReceiver,
-          abstractArguments);
+      _inliner.cache.putNegative(
+          target, callStructure, abstractReceiverInMethod, abstractArguments);
       return null;
     }
     if (backend.annotations.noInline(target)) return doNotInline();
@@ -412,11 +440,19 @@
       void setValue(Variable variable, Reference<Primitive> value) {
         variable.type = value.definition.type;
       }
-      if (invoke.receiver != null) {
+      if (invoke.callingConvention == CallingConvention.Intercepted) {
         setValue(function.thisParameter, invoke.receiver);
-      }
-      for (int i = 0; i < invoke.arguments.length; ++i) {
-        setValue(function.parameters[i], invoke.arguments[i]);
+        function.parameters[0].type = abstractReceiverInMethod;
+        for (int i = 1; i < invoke.arguments.length; ++i) {
+          setValue(function.parameters[i], invoke.arguments[i]);
+        }
+      } else {
+        if (invoke.receiver != null) {
+          function.thisParameter.type = abstractReceiverInMethod;
+        }
+        for (int i = 0; i < invoke.arguments.length; ++i) {
+          setValue(function.parameters[i], invoke.arguments[i]);
+        }
       }
       optimizeBeforeInlining(function);
     }
@@ -429,25 +465,9 @@
     int size = SizeVisitor.sizeOf(invoke, function);
     if (!_inliner.isCalledOnce(target) && size > 11) return doNotInline();
 
-    _inliner.cache.putPositive(target, callStructure, abstractReceiver,
+    _inliner.cache.putPositive(target, callStructure, abstractReceiverInMethod,
         abstractArguments, function);
-    _fragment = new CpsFragment(invoke.sourceInformation);
-    Primitive receiver = invoke.receiver?.definition;
-    List<Primitive> arguments =
-        invoke.arguments.map((Reference ref) => ref.definition).toList();
-    if (dartReceiver != null && abstractReceiver.isNullable) {
-      Primitive check =
-          _fragment.letPrim(new NullCheck(dartReceiver.definition,
-              invoke.sourceInformation));
-      check.type = abstractReceiver.nonNullable();
-      if (invoke.callingConvention == CallingConvention.Intercepted) {
-        arguments[0] = check;
-      } else {
-        receiver = check;
-      }
-    }
-    return _fragment.inlineFunction(function, receiver, arguments,
-        hint: invoke.hint);
+    return finish(function);
   }
 
   Primitive nullReceiverGuard(InvocationPrimitive invoke,
@@ -469,7 +489,8 @@
     }
 
     Primitive check = _fragment.letPrim(
-        new NullCheck(dartReceiver, invoke.sourceInformation));
+        new NullCheck(dartReceiver, invoke.sourceInformation,
+                      selector: selector));
     check.type = abstractReceiver.nonNullable();
     return check;
   }
diff --git a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
index 99d1807..207753f 100644
--- a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
+++ b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
@@ -4,10 +4,13 @@
 
 library cps_ir.optimization.insert_refinements;
 
+import 'dart:math' show min;
 import 'optimizers.dart' show Pass;
 import 'cps_ir_nodes.dart';
+import '../elements/elements.dart';
 import '../common/names.dart';
 import '../types/types.dart' show TypeMask;
+import '../universe/selector.dart';
 import 'type_mask_system.dart';
 
 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive
@@ -104,6 +107,32 @@
     });
   }
 
+  /// Refine the type of each argument on [node] according to the provided
+  /// type masks.
+  void _refineArguments(
+      InvocationPrimitive node, List<TypeMask> argumentSuccessTypes) {
+    if (argumentSuccessTypes == null) return;
+
+    // Note: node.dartArgumentsLength is shorter when the call doesn't include
+    // some optional arguments.
+    int length = min(argumentSuccessTypes.length, node.dartArgumentsLength);
+    for (int i = 0; i < length; i++) {
+      TypeMask argSuccessType = argumentSuccessTypes[i];
+
+      // Skip arguments that provide no refinement.
+      if (argSuccessType == types.dynamicType) continue;
+
+      applyRefinement(node.parent,
+          new Refinement(node.dartArgument(i), argSuccessType));
+    }
+  }
+
+  void visitInvokeStatic(InvokeStatic node) {
+    node.arguments.forEach(processReference);
+    _refineArguments(node,
+        _getSuccessTypesForStaticMethod(types, node.target));
+  }
+
   void visitInvokeMethod(InvokeMethod node) {
     // Update references to their current refined values.
     processReference(node.receiver);
@@ -115,12 +144,18 @@
 
     // Do not try to refine the receiver of closure calls; the class world
     // does not know about closure classes.
-    if (!node.selector.isClosureCall) {
+    Selector selector = node.selector;
+    if (!selector.isClosureCall) {
       // Filter away receivers that throw on this selector.
-      TypeMask type = types.receiverTypeFor(node.selector, node.mask);
+      TypeMask type = types.receiverTypeFor(selector, node.mask);
       Refinement refinement = new Refinement(receiver, type);
       LetPrim letPrim = node.parent;
       applyRefinement(letPrim, refinement);
+
+      // Refine arguments of methods on numbers which we know will throw on
+      // invalid argument values.
+      _refineArguments(node,
+          _getSuccessTypesForInstanceMethod(types, type, selector));
     }
   }
 
@@ -233,3 +268,168 @@
     return node.body;
   }
 }
+
+// TODO(sigmund): ideally this whitelist information should be stored as
+// metadata annotations on the runtime libraries so we can keep it in sync with
+// the implementation more easily.
+// TODO(sigmund): add support for constructors.
+// TODO(sigmund): add checks for RegExp and DateTime (currently not exposed as
+// easily in TypeMaskSystem).
+// TODO(sigmund): after the above TODOs are fixed, add:
+//   ctor JSArray.fixed: [types.uint32Type],
+//   ctor JSArray.growable: [types.uintType],
+//   ctor DateTime': [int, int, int, int, int, int, int],
+//   ctor DateTime.utc': [int, int, int, int, int, int, int],
+//   ctor DateTime._internal': [int, int, int, int, int, int, int, bool],
+//   ctor RegExp': [string, dynamic, dynamic],
+//   method RegExp.allMatches: [string, int],
+//   method RegExp.firstMatch: [string],
+//   method RegExp.hasMatch: [string],
+List<TypeMask> _getSuccessTypesForInstanceMethod(
+    TypeMaskSystem types, TypeMask receiver, Selector selector) {
+  if (types.isDefinitelyInt(receiver)) {
+    switch (selector.name) {
+      case 'toSigned':
+      case 'toUnsigned':
+      case 'modInverse':
+      case 'gcd':
+        return [types.intType];
+
+      case 'modPow':
+       return [types.intType, types.intType];
+    }
+    // Note: num methods on int values are handled below.
+  }
+
+  if (types.isDefinitelyNum(receiver)) {
+    switch (selector.name) {
+      case 'clamp':
+          return [types.numType, types.numType];
+      case 'toStringAsFixed':
+      case 'toStringAsPrecision':
+      case 'toRadixString':
+          return [types.intType];
+      case 'toStringAsExponential':
+          return [types.intType.nullable()];
+      case 'compareTo':
+      case 'remainder':
+      case '+':
+      case '-':
+      case '/':
+      case '*':
+      case '%':
+      case '~/':
+      case '<<':
+      case '>>':
+      case '&':
+      case '|':
+      case '^':
+      case '<':
+      case '>':
+      case '<=':
+      case '>=':
+          return [types.numType];
+      default:
+        return null;
+    }
+  }
+
+  if (types.isDefinitelyString(receiver)) {
+    switch (selector.name) {
+      case 'allMatches':
+        return [types.stringType, types.intType];
+      case 'endsWith':
+        return [types.stringType];
+      case 'replaceAll':
+        return [types.dynamicType, types.stringType];
+      case 'replaceFirst':
+        return [types.dynamicType, types.stringType, types.intType];
+      case 'replaceFirstMapped':
+        return [
+          types.dynamicType,
+          types.dynamicType.nonNullable(),
+          types.intType
+        ];
+      case 'split':
+        return [types.dynamicType.nonNullable()];
+      case 'replaceRange':
+        return [types.intType, types.intType, types.stringType];
+      case 'startsWith':
+        return [types.dynamicType, types.intType];
+      case 'substring':
+        return [types.intType, types.uintType.nullable()];
+      case 'indexOf':
+        return [types.dynamicType.nonNullable(), types.uintType];
+      case 'lastIndexOf':
+        return [types.dynamicType.nonNullable(), types.uintType.nullable()];
+      case 'contains':
+        return [
+          types.dynamicType.nonNullable(),
+          // TODO(sigmund): update runtime to add check for int?
+          types.dynamicType
+        ];
+      case 'codeUnitAt':
+        return [types.uintType];
+      case '+':
+        return [types.stringType];
+      case '*':
+        return [types.uint32Type];
+      case '[]':
+        return [types.uintType];
+      default:
+        return null;
+    }
+  }
+
+  if (types.isDefinitelyArray(receiver)) {
+    switch (selector.name) {
+      case 'removeAt':
+      case 'insert':
+        return [types.uintType];
+      case 'sublist':
+        return [types.uintType, types.uintType.nullable()];
+      case 'length':
+         return selector.isSetter ? [types.uintType] : null;
+      case '[]':
+      case '[]=':
+        return [types.uintType];
+      default:
+        return null;
+    }
+  }
+  return null;
+}
+
+List<TypeMask> _getSuccessTypesForStaticMethod(
+    TypeMaskSystem types, FunctionElement target) {
+  var lib = target.library;
+  if (lib.isDartCore) {
+    var cls = target.enclosingClass?.name;
+    if (cls == 'int' && target.name == 'parse') {
+      // source, onError, radix
+      return [types.stringType, types.dynamicType, types.uint31Type.nullable()];
+    } else if (cls == 'double' && target.name == 'parse') {
+      return [types.stringType, types.dynamicType];
+    }
+  }
+
+  if (lib.isPlatformLibrary && '${lib.canonicalUri}' == 'dart:math') {
+    switch(target.name) {
+      case 'sqrt':
+      case 'sin':
+      case 'cos':
+      case 'tan':
+      case 'acos':
+      case 'asin':
+      case 'atan':
+      case 'atan2':
+      case 'exp':
+      case 'log':
+        return [types.numType];
+      case 'pow':
+        return [types.numType, types.numType];
+    }
+  }
+
+  return null;
+}
diff --git a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
index 99b1105..897a44e 100644
--- a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
+++ b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
@@ -5,6 +5,7 @@
 library dart2js.cps_ir.loop_hierarchy;
 
 import 'cps_ir_nodes.dart';
+import 'cps_fragment.dart';
 
 /// Determines the effective nesting of loops.
 ///
@@ -33,7 +34,10 @@
   Map<Continuation, Continuation> loopTarget = <Continuation, Continuation>{};
 
   /// Current nesting depth.
-  int currentDepth = 0;
+  int _currentDepth = 0;
+
+  /// The loop target to use for missing code.  Used by [update].
+  Continuation _exitLoop;
 
   /// Computes the loop hierarchy for the given function.
   ///
@@ -88,11 +92,11 @@
   /// from the current exception handler.
   Continuation _processContinuation(Continuation cont, Continuation catchLoop) {
     if (cont.isRecursive) {
-      ++currentDepth;
-      loopDepth[cont] = currentDepth;
+      ++_currentDepth;
+      loopDepth[cont] = _currentDepth;
       Continuation target = _processBlock(cont.body, catchLoop);
       _markInnerLoop(loopTarget[cont], target);
-      --currentDepth;
+      --_currentDepth;
     } else {
       loopTarget[cont] = _processBlock(cont.body, catchLoop);
     }
@@ -102,7 +106,7 @@
   /// Analyzes a basic block and returns the innermost loop that
   /// can be invoked recursively from that block.
   Continuation _processBlock(Expression node, Continuation catchLoop) {
-    for (; node is! TailExpression; node = node.next) {
+    for (; node != null && node is! TailExpression; node = node.next) {
       if (node is LetCont) {
         for (Continuation cont in node.continuations) {
           _processContinuation(cont, catchLoop);
@@ -122,8 +126,11 @@
       target = _markInnerLoop(
           loopTarget[node.trueContinuation.definition],
           loopTarget[node.falseContinuation.definition]);
+    } else if (node == null) {
+      // If the code ends abruptly, use the exit loop provided in [update].
+      target = _exitLoop;
     } else {
-      assert(node is Unreachable || node is Throw);
+      assert(node is Unreachable || node is Throw || node == null);
     }
     return _markInnerLoop(target, catchLoop);
   }
@@ -149,4 +156,22 @@
     if (loop == null) return 0;
     return loopDepth[loop];
   }
+
+  /// Sets the loop header for each continuation bound inside the given
+  /// fragment.
+  ///
+  /// If the fragment is open, [exitLoop] denotes the loop header for
+  /// the code that will occur after the fragment.
+  ///
+  /// [catchLoop] is the loop target for the catch clause of the try/catch
+  /// surrounding the inserted fragment.
+  void update(CpsFragment fragment,
+              {Continuation exitLoop,
+               Continuation catchLoop}) {
+    if (fragment.isEmpty) return;
+    _exitLoop = exitLoop;
+    _currentDepth = getDepth(exitLoop);
+    _processBlock(fragment.root, catchLoop);
+    _exitLoop = null;
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart b/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart
new file mode 100644
index 0000000..e9f04a6
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart
@@ -0,0 +1,252 @@
+library dart2js.cps_ir.loop_invariant_branch;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart';
+import 'loop_hierarchy.dart';
+import 'cps_fragment.dart';
+import 'redundant_join.dart' show AlphaRenamer;
+
+/// Hoists branches out of loops, where:
+/// - the branch is at the entry point of a loop
+/// - the branch condition is loop-invariant
+/// - one arm of the branch is not effectively part of the loop
+///
+/// Schematically:
+///
+///     b = COND
+///     while (true) {
+///       if (b)
+///         BRANCH (contains no continue to loop)
+///       else
+///         LOOP
+///     }
+///
+///     ==>
+///
+///     b = COND
+///     if (b)
+///       BRANCH
+///     else
+///       while (true)
+///         LOOP
+///
+/// As in [RedundantJoinEliminator], parameters are treated as names with
+/// lexical scoping during this pass, and a given parameter "name" may be
+/// declared by more than one continuation. The reference chains for parameters
+/// are therefore meaningless during this pass, until repaired by [AlphaRenamer]
+/// at the end.
+class LoopInvariantBranchMotion extends BlockVisitor implements Pass {
+  String get passName => 'Loop invariant branch motion';
+
+  LoopHierarchy loopHierarchy;
+  final Map<Primitive, Continuation> loopHeaderFor =
+      <Primitive, Continuation>{};
+  final Map<Continuation, Continuation> catchLoopFor =
+      <Continuation, Continuation>{};
+  Continuation currentLoopHeader;
+  Continuation currentCatchLoop;
+  List<Continuation> loops = <Continuation>[];
+  bool wasHoisted = false;
+
+  void rewrite(FunctionDefinition node) {
+    loopHierarchy = new LoopHierarchy(node);
+    BlockVisitor.traverseInPreOrder(node, this);
+    // Process loops bottom-up so a branch can be hoisted multiple times.
+    loops.reversed.forEach(hoistEntryCheck);
+    if (wasHoisted) {
+      new AlphaRenamer().visit(node);
+    }
+  }
+
+  void visitLetHandler(LetHandler node) {
+    currentCatchLoop = loopHierarchy.getLoopHeader(node.handler);
+  }
+
+  void visitContinuation(Continuation node) {
+    currentLoopHeader = loopHierarchy.getLoopHeader(node);
+    for (Parameter param in node.parameters) {
+      loopHeaderFor[param] = currentLoopHeader;
+    }
+    catchLoopFor[node] = currentCatchLoop;
+    if (node.isRecursive) {
+      loops.add(node);
+    }
+  }
+
+  void visitLetPrim(LetPrim node) {
+    loopHeaderFor[node.primitive] = currentLoopHeader;
+  }
+
+  void hoistEntryCheck(Continuation loop) {
+    // Keep hoisting branches out of the loop, there can be more than one.
+    while (tryHoistEntryCheck(loop));
+  }
+
+  Expression getEffectiveBody(Expression exp) {
+    // TODO(asgerf): We could also bypass constants here but constant pooling
+    //               is likely to be a better solution for that.
+    while (exp is LetCont) {
+      exp = exp.next;
+    }
+    return exp;
+  }
+
+  /// Adds [parameters] to [cont] and updates every invocation to pass the
+  /// corresponding parameter values as arguments. Thus, the parameters are
+  /// passed in explicitly instead of being captured.
+  ///
+  /// This only works because [AlphaRenamer] cleans up at the end of this pass.
+  ///
+  /// Schematically:
+  ///
+  ///     let outer(x1, x2, x3) =
+  ///       let inner(y) = BODY
+  ///       [ .. inner(y') .. ]
+  ///
+  ///   ==> (append parameters)
+  ///
+  ///     let outer(x1, x2, x3) =
+  ///       let inner(y, x1, x2, x3) = BODY
+  ///       [ .. inner(y', x1, x2, x3) .. ]
+  ///
+  ///   ==> (hoist, not performed by this method)
+  ///
+  ///     let inner(y, x1, x2, x3) = BODY
+  ///     let outer(x1, x2, x3) =
+  ///       [ .. inner(y', x1, x2, x3) .. ]
+  ///
+  void appendParameters(Continuation cont, List<Parameter> parameters) {
+    cont.parameters.addAll(parameters);
+    for (Reference ref = cont.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is InvokeContinuation) {
+        for (Parameter loopParam in parameters) {
+          use.arguments.add(new Reference<Primitive>(loopParam)..parent = use);
+        }
+      }
+    }
+  }
+
+  bool tryHoistEntryCheck(Continuation loop) {
+    // Check if this is a loop starting with a branch.
+    Expression body = getEffectiveBody(loop.body);
+    if (body is! Branch) return false;
+    Branch branch = body;
+
+    // Is the condition loop invariant?
+    Primitive condition = branch.condition.definition;
+    if (loopHeaderFor[condition] == loop) return false;
+
+    Continuation trueCont = branch.trueContinuation.definition;
+    Continuation falseCont = branch.falseContinuation.definition;
+    Continuation hoistedCase; // The branch to hoist.
+    Continuation loopCase; // The branch that is part of the loop.
+
+    // Check that one branch is part of the loop, and the other is an exit.
+    if (loopHierarchy.getLoopHeader(trueCont) != loop &&
+        loopHierarchy.getLoopHeader(falseCont) == loop) {
+      hoistedCase = trueCont;
+      loopCase = falseCont;
+    } else if (loopHierarchy.getLoopHeader(falseCont) != loop &&
+               loopHierarchy.getLoopHeader(trueCont) == loop) {
+      hoistedCase = falseCont;
+      loopCase = trueCont;
+    } else {
+      return false;
+    }
+
+    // Hoist non-loop continuations out of the loop.
+    // The hoisted branch can reference other continuations bound in the loop,
+    // so to stay in scope, those need to be hoisted as well.
+    //
+    //     let b = COND
+    //     let loop(x) =
+    //       let join(y) = JOIN
+    //       let hoistCase() = HOIST
+    //       let loopCase() = LOOP
+    //       branch b hoistCase loopCase
+    //     in loop(i)
+    //
+    //    ==>
+    //
+    //     let b = COND
+    //     let join(y,x) = JOIN
+    //     let hoistCase(x) = HOIST
+    //     let loop(x) =
+    //       let loopCase() = LOOP
+    //       branch b hoistCase loopCase
+    //     in loop(i)
+    //
+    LetCont loopBinding = loop.parent;
+    Expression it = loop.body;
+    while (it is LetCont) {
+      LetCont let = it;
+      it = let.body;
+      for (Continuation cont in let.continuations) {
+        if (loopHierarchy.getEnclosingLoop(cont) != loop) {
+          appendParameters(cont, loop.parameters);
+          new LetCont(cont, null).insertAbove(loopBinding);
+        }
+      }
+      let.continuations.removeWhere((cont) => cont.parent != let);
+      if (let.continuations.isEmpty) {
+        let.remove();
+      }
+    }
+
+    // Create a new branch to call the hoisted continuation or the loop:
+    //
+    //     let loop(x) =
+    //       let loopCase() = LOOP
+    //       branch b hoistCase loopCase
+    //     in loop(i)
+    //
+    //    ==>
+    //
+    //     let newTrue() = hoistCase(i)
+    //     let newFalse() =
+    //       let loop(x) =
+    //         let loopCase() = LOOP
+    //         branch b hoistCase loopCase
+    //     branch b newTrue newFalse
+    //
+    InvokeContinuation loopEntry = loopBinding.body;
+    List<Primitive> loopArgs =
+        loopEntry.arguments.map((ref) => ref.definition).toList();
+    CpsFragment cps = new CpsFragment();
+    cps.branch(condition,
+          strict: branch.isStrictCheck,
+          negate: hoistedCase == falseCont)
+       .invokeContinuation(hoistedCase, loopArgs);
+
+    // The continuations created in the fragment need to have their loop header
+    // set so the loop hierarchy remains intact
+    loopHierarchy.update(cps,
+        exitLoop: loopHierarchy.getEnclosingLoop(loop),
+        catchLoop: catchLoopFor[loop]);
+
+    // Insert above the loop. This will put the loop itself in a branch.
+    cps.insertAbove(loopBinding);
+
+    // Replace the old branch with the loopCase, still bound inside the loop:
+    //
+    //   let loop(x) =
+    //     let loopCase() = LOOP
+    //     branch b hoistCase loopCase
+    //   in loop(i)
+    //
+    //  ==>
+    //
+    //   let loop(x) =
+    //     let loopCase() = LOOP
+    //     loopCase()
+    //   in loop(i)
+    //
+    destroyAndReplace(branch, new InvokeContinuation(loopCase, []));
+
+    // Record that at least one branch was hoisted to trigger alpha renaming.
+    wasHoisted = true;
+
+    return true;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
index 19b79d4..689dac6 100644
--- a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
@@ -14,22 +14,28 @@
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../types/types.dart' show TypeMask;
 import '../io/source_information.dart' show SourceInformation;
+import '../world.dart';
+import 'type_mask_system.dart';
 
 /// Replaces `getInterceptor` calls with interceptor constants when possible,
 /// or with "almost constant" expressions like "x && CONST" when the input
 /// is either null or has a known interceptor.
-//
-//  TODO(asgerf): Compute intercepted classes in this pass.
+///
+/// Narrows the set of intercepted classes for interceptor calls.
+///
+/// Replaces calls on interceptors with one-shot interceptors.
 class OptimizeInterceptors extends TrampolineRecursiveVisitor implements Pass {
   String get passName => 'Optimize interceptors';
 
-  JavaScriptBackend backend;
+  final TypeMaskSystem typeSystem;
+  final JavaScriptBackend backend;
   LoopHierarchy loopHierarchy;
   Continuation currentLoopHeader;
 
-  OptimizeInterceptors(this.backend);
+  OptimizeInterceptors(this.backend, this.typeSystem);
 
   BackendHelpers get helpers => backend.helpers;
+  World get classWorld => backend.compiler.world;
 
   Map<Interceptor, Continuation> loopHeaderFor = <Interceptor, Continuation>{};
 
@@ -51,17 +57,6 @@
     return cont.body;
   }
 
-  /// If only one method table can be returned by the given interceptor,
-  /// returns a constant for that method table.
-  InterceptorConstantValue getInterceptorConstant(Interceptor node) {
-    if (node.interceptedClasses.length == 1 &&
-        node.isInterceptedClassAlwaysExact) {
-      ClassElement interceptorClass = node.interceptedClasses.single;
-      return new InterceptorConstantValue(interceptorClass.rawType);
-    }
-    return null;
-  }
-
   bool hasNoFalsyValues(ClassElement class_) {
     return class_ != helpers.jsInterceptorClass &&
        class_ != helpers.jsNullClass &&
@@ -103,13 +98,113 @@
     return prim;
   }
 
+  void computeInterceptedClasses(Interceptor interceptor) {
+    Set<ClassElement> intercepted = interceptor.interceptedClasses;
+    intercepted.clear();
+    for (Reference ref = interceptor.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is InvokeMethod) {
+        TypeMask type = use.dartReceiver.type;
+        bool canOccurAsReceiver(ClassElement elem) {
+          return classWorld.isInstantiated(elem) &&
+              !typeSystem.areDisjoint(type,
+                  typeSystem.getInterceptorSubtypes(elem));
+        }
+        Iterable<ClassElement> classes =
+            backend.getInterceptedClassesOn(use.selector.name);
+        intercepted.addAll(classes.where(canOccurAsReceiver));
+      } else {
+        intercepted.clear();
+        intercepted.add(backend.helpers.jsInterceptorClass);
+        break;
+      }
+    }
+    if (intercepted.contains(backend.helpers.jsInterceptorClass) ||
+        intercepted.contains(backend.helpers.jsNullClass)) {
+      // If the null value is intercepted, update the type of the interceptor.
+      // The Tree IR uses this information to determine if the method lookup
+      // on an InvokeMethod might throw.
+      interceptor.type = interceptor.type.nonNullable();
+    }
+  }
+
+  /// True if [node] may return [JSNumber] instead of [JSInt] or [JSDouble].
+  bool jsNumberClassSuffices(Interceptor node) {
+    // No methods on JSNumber call 'down' to methods on JSInt or JSDouble.  If
+    // all uses of the interceptor are for methods is defined only on JSNumber
+    // then JSNumber will suffice in place of choosing between JSInt or
+    // JSDouble.
+    for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
+      if (ref.parent is InvokeMethod) {
+        InvokeMethod invoke = ref.parent;
+        if (invoke.receiver != ref) return false;
+        var interceptedClasses =
+            backend.getInterceptedClassesOn(invoke.selector.name);
+        if (interceptedClasses.contains(helpers.jsDoubleClass)) return false;
+        if (interceptedClasses.contains(helpers.jsIntClass)) return false;
+        continue;
+      }
+      // Other uses need full distinction.
+      return false;
+    }
+    return true;
+  }
+
+  /// True if [node] can intercept a `null` value and return the [JSNull]
+  /// interceptor.
+  bool canInterceptNull(Interceptor node) {
+    for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is InvokeMethod) {
+        if (selectorsOnNull.contains(use.selector) &&
+            use.dartReceiver.type.isNullable) {
+          return true;
+        }
+      } else {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Returns the only interceptor class that may be returned by [node], or
+  /// `null` if no such class could be found.
+  ClassElement getSingleInterceptorClass(Interceptor node) {
+    // TODO(asgerf): This could be more precise if we used the use-site type,
+    // since the interceptor may have been hoisted out of a loop, where a less
+    // precise type is known.
+    Primitive input = node.input.definition;
+    TypeMask type = input.type;
+    if (canInterceptNull(node)) return null;
+    type = type.nonNullable();
+    if (typeSystem.isDefinitelyArray(type)) {
+      return backend.helpers.jsArrayClass;
+    }
+    if (typeSystem.isDefinitelyInt(type)) {
+      return backend.helpers.jsIntClass;
+    }
+    if (typeSystem.isDefinitelyNum(type) && jsNumberClassSuffices(node)) {
+      return backend.helpers.jsNumberClass;
+    }
+    ClassElement singleClass = type.singleClass(classWorld);
+    if (singleClass != null &&
+        singleClass.isSubclassOf(backend.helpers.jsInterceptorClass)) {
+      return singleClass;
+    }
+    return null;
+  }
+
+  /// Try to replace [interceptor] with a constant, and return `true` if
+  /// successful.
   bool constifyInterceptor(Interceptor interceptor) {
     LetPrim let = interceptor.parent;
-    InterceptorConstantValue constant = getInterceptorConstant(interceptor);
+    Primitive input = interceptor.input.definition;
+    ClassElement classElement = getSingleInterceptorClass(interceptor);
 
-    if (constant == null) return false;
+    if (classElement == null) return false;
+    ConstantValue constant = new InterceptorConstantValue(classElement.rawType);
 
-    if (interceptor.isAlwaysIntercepted) {
+    if (!input.type.isNullable) {
       Primitive constantPrim = makeConstantFor(constant,
           useSite: let,
           type: interceptor.type,
@@ -117,8 +212,7 @@
       constantPrim.useElementAsHint(interceptor.hint);
       interceptor..replaceUsesWith(constantPrim)..destroy();
       let.remove();
-    } else if (interceptor.isAlwaysNullOrIntercepted) {
-      Primitive input = interceptor.input.definition;
+    } else {
       Primitive constantPrim = makeConstantFor(constant,
           useSite: let,
           type: interceptor.type.nonNullable(),
@@ -127,7 +221,7 @@
       Parameter param = new Parameter(interceptor.hint);
       param.type = interceptor.type;
       Continuation cont = cps.letCont(<Parameter>[param]);
-      if (interceptor.interceptedClasses.every(hasNoFalsyValues)) {
+      if (hasNoFalsyValues(classElement)) {
         // If null is the only falsy value, compile as "x && CONST".
         cps.ifFalsy(input).invokeContinuation(cont, [input]);
       } else {
@@ -156,6 +250,7 @@
   @override
   void visitInterceptor(Interceptor node) {
     if (constifyInterceptor(node)) return;
+    computeInterceptedClasses(node);
     if (node.hasExactlyOneUse) {
       // Set the loop header on single-use interceptors so [visitInvokeMethod]
       // can determine if it should become a one-shot interceptor.
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 0ca2173..812b204 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -6,6 +6,8 @@
 
 import 'cps_ir_nodes.dart';
 import '../constants/values.dart';
+import '../common/names.dart';
+import '../universe/selector.dart';
 
 export 'type_propagation.dart' show TypePropagator;
 export 'scalar_replacement.dart' show ScalarReplacer;
@@ -22,6 +24,7 @@
 export 'gvn.dart' show GVN;
 export 'inline.dart' show Inliner;
 export 'eagerly_load_statics.dart' show EagerlyLoadStatics;
+export 'loop_invariant_branch.dart' show LoopInvariantBranchMotion;
 export 'parent_visitor.dart' show ParentVisitor;
 
 /// An optimization pass over the CPS IR.
@@ -51,3 +54,9 @@
 bool isTruthyConstant(ConstantValue value, {bool strict: false}) {
   return strict ? value.isTrue : !isFalsyConstant(value);
 }
+
+/// Selectors that do not throw when invoked on the null value.
+final List<Selector> selectorsOnNull = <Selector>[
+    Selectors.equals, Selectors.hashCode_, Selectors.runtimeType_,
+    Selectors.toString_, Selectors.toStringGetter,
+    Selectors.noSuchMethodGetter];
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index f7365b4..16a1d15 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -6,6 +6,7 @@
 
 import 'cps_ir_nodes.dart';
 import 'optimizers.dart';
+import 'cps_fragment.dart';
 
 /**
  * [ShrinkingReducer] applies shrinking reductions to CPS terms as described
@@ -91,7 +92,8 @@
     assert(_isDeadVal(task.node));
 
     // Remove dead primitive.
-    LetPrim letPrim = task.node;;
+    LetPrim letPrim = task.node;
+    destroyRefinementsOfDeadPrimitive(letPrim.primitive);
     _removeNode(letPrim);
 
     // Perform bookkeeping on removed body and scan for new redexes.
@@ -139,6 +141,7 @@
     // Substitute the invocation argument for the continuation parameter.
     for (int i = 0; i < invoke.arguments.length; i++) {
       cont.parameters[i].replaceUsesWith(invoke.arguments[i].definition);
+      invoke.arguments[i].definition.useElementAsHint(cont.parameters[i].hint);
     }
 
     // Perform bookkeeping on substituted body and scan for new redexes.
@@ -166,6 +169,10 @@
     InvokeContinuation invoke = cont.body;
     Continuation wrappedCont = invoke.continuation.definition;
 
+    for (int i = 0; i < cont.parameters.length; ++i) {
+      wrappedCont.parameters[i].useElementAsHint(cont.parameters[i].hint);
+    }
+
     // If the invocation of wrappedCont is escaping, then all invocations of
     // cont will be as well, after the reduction.
     if (invoke.isEscapingTry) {
@@ -242,7 +249,8 @@
 /// Returns true iff the bound primitive is unused, and has no effects
 /// preventing it from being eliminated.
 bool _isDeadVal(LetPrim node) {
-  return node.primitive.hasNoUses && node.primitive.isSafeForElimination;
+  return node.primitive.hasNoEffectiveUses &&
+         node.primitive.isSafeForElimination;
 }
 
 /// Returns true iff the continuation is unused.
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 3b340b2..aa26e31 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -670,10 +670,10 @@
   }
 
   /// The possible return types of a method that may be targeted by
-  /// [typedSelector]. If the given selector is not a [TypedSelector], any
-  /// reachable method matching the selector may be targeted.
-  AbstractConstantValue getInvokeReturnType(Selector selector, TypeMask mask) {
-    return fromMask(typeSystem.getInvokeReturnType(selector, mask));
+  /// [selector] on [receiver].
+  AbstractConstantValue getInvokeReturnType(
+      Selector selector, AbstractConstantValue receiver) {
+    return fromMask(typeSystem.getInvokeReturnType(selector, receiver.type));
   }
 
   AbstractConstantValue fromMask(TypeMask mask) {
@@ -1388,6 +1388,28 @@
         assert(node.hasNoUses);
         return cps;
 
+      case 'isEmpty':
+        if (!node.selector.isGetter) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        Primitive length = cps.letPrim(new GetLength(receiver));
+        Constant zero = cps.makeZero();
+        ApplyBuiltinOperator op = cps.applyBuiltin(BuiltinOperator.StrictEq,
+                                                   [length, zero]);
+        node.replaceUsesWith(op);
+        op.hint = node.hint;
+        return cps;
+
+      case 'isNotEmpty':
+        if (!node.selector.isGetter) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        Primitive length = cps.letPrim(new GetLength(receiver));
+        Constant zero = cps.makeZero();
+        ApplyBuiltinOperator op = cps.applyBuiltin(BuiltinOperator.StrictNeq,
+                                                   [length, zero]);
+        node.replaceUsesWith(op);
+        op.hint = node.hint;
+        return cps;
+
       default:
         return null;
     }
@@ -1751,7 +1773,7 @@
         new Selector.call(getter.memberName, call.callStructure),
         type,
         node.arguments.map((ref) => ref.definition).toList(),
-        node.sourceInformation);
+        sourceInformation: node.sourceInformation);
       node.receiver.changeTo(new Parameter(null)); // Remove the tear off use.
 
       if (tearOff.hasNoEffectiveUses) {
@@ -1835,6 +1857,30 @@
     return cps;
   }
 
+  visitInterceptor(Interceptor node) {
+    // Replace the interceptor with its input if the value is not intercepted.
+    // If the input might be null, we cannot do this since the interceptor
+    // might have to return JSNull.  That case is handled by visitInvokeMethod
+    // and visitInvokeMethodDirectly which can sometimes tolerate that null
+    // is used instead of JSNull.
+    Primitive input = node.input.definition;
+    if (!input.type.isNullable &&
+        typeSystem.areDisjoint(input.type, typeSystem.interceptorType)) {
+      node.replaceUsesWith(input);
+    }
+  }
+
+  visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    TypeMask receiverType = node.dartReceiver.type;
+    if (node.callingConvention == CallingConvention.Intercepted &&
+        typeSystem.areDisjoint(receiverType, typeSystem.interceptorType)) {
+      // Some direct calls take an interceptor because the target class is
+      // mixed into a native class.  If it is known at the call site that the
+      // receiver is non-intercepted, get rid of the interceptor.
+      node.receiver.changeTo(node.dartReceiver);
+    }
+  }
+
   visitInvokeMethod(InvokeMethod node) {
     var specialized =
         specializeOperatorCall(node) ??
@@ -1845,15 +1891,19 @@
         specializeClosureCall(node);
     if (specialized != null) return specialized;
 
-    node.mask =
-      typeSystem.intersection(node.mask, getValue(node.dartReceiver).type);
+    TypeMask receiverType = node.dartReceiver.type;
+    node.mask = typeSystem.intersection(node.mask, receiverType);
 
-    AbstractConstantValue receiver = getValue(node.receiver.definition);
+    bool canBeNonThrowingCallOnNull =
+        selectorsOnNull.contains(node.selector) &&
+        receiverType.isNullable;
 
     if (node.callingConvention == CallingConvention.Intercepted &&
-        node.receiver.definition.sameValue(node.arguments[0].definition)) {
-      // The receiver and first argument are the same; that means we already
-      // determined in visitInterceptor that we are targeting a non-interceptor.
+        !canBeNonThrowingCallOnNull &&
+        typeSystem.areDisjoint(receiverType, typeSystem.interceptorType)) {
+      // Use the Dart receiver as the JS receiver. This changes the wording of
+      // the error message when the receiver is null, but we accept this.
+      node.receiver.changeTo(node.dartReceiver);
 
       // Check if any of the possible targets depend on the extra receiver
       // argument. Mixins do this, and tear-offs always needs the extra receiver
@@ -1866,7 +1916,7 @@
         return typeSystem.methodUsesReceiverArgument(function) ||
                node.selector.isGetter && !function.isGetter;
       }
-      if (!getAllTargets(receiver.type, node.selector).any(needsReceiver)) {
+      if (!getAllTargets(receiverType, node.selector).any(needsReceiver)) {
         // Replace the extra receiver argument with a dummy value if the
         // target definitely does not use it.
         Constant dummy = makeConstantPrimitive(new IntConstantValue(0));
@@ -1914,94 +1964,8 @@
     return null;
   }
 
-  /// Try to inline static invocations.
-  ///
-  /// Performs the inlining and returns true if the call was inlined.  Inlining
-  /// uses a fixed heuristic:
-  ///
-  /// * Inline functions with a single expression statement or return statement
-  /// provided that the subexpression is an invocation of foreign code.
-  inlineInvokeStatic(InvokeStatic node) {
-    // The target might not have an AST, for example if it deferred.
-    if (!node.target.hasNode) return null;
-
-    if (node.target.asyncMarker != AsyncMarker.SYNC) {
-      // Inlining of async/sync*/async* methods is currently not supported.
-      return null;
-    }
-
-    // True if an expression is non-expansive, in the sense defined by this
-    // predicate.
-    bool isNonExpansive(ast.Expression expr) {
-      if (expr is ast.LiteralNull ||
-          expr is ast.LiteralBool ||
-          expr is ast.LiteralInt ||
-          expr is ast.LiteralDouble) {
-        return true;
-      }
-      if (expr is ast.Send) {
-        SendStructure structure =
-            node.target.treeElements.getSendStructure(expr);
-        if (structure is InvokeStructure) {
-          // Calls to foreign functions.
-          return structure.semantics.kind == AccessKind.TOPLEVEL_METHOD &&
-              backend.isForeign(structure.semantics.element);
-        } else if (structure is IsStructure || structure is IsNotStructure) {
-          // is and is! checks on nonexpansive expressions.
-          return isNonExpansive(expr.receiver);
-        } else if (structure is EqualsStructure ||
-            structure is NotEqualsStructure) {
-          // == and != on nonexpansive expressions.
-          return isNonExpansive(expr.receiver) &&
-              isNonExpansive(expr.argumentsNode.nodes.head);
-        } else if (structure is GetStructure) {
-          // Parameters.
-          return structure.semantics.kind == AccessKind.PARAMETER;
-        }
-      }
-      return false;
-    }
-
-    ast.Statement body = node.target.node.body;
-    bool shouldInline() {
-      if (backend.annotations.noInline(node.target)) return false;
-      if (node.target.resolvedAst.elements.containsTryStatement) return false;
-
-      // Inline functions that are a single return statement, expression
-      // statement, or block containing a return statement or expression
-      // statement.
-      if (body is ast.Return) {
-        return isNonExpansive(body.expression);
-      } else if (body is ast.ExpressionStatement) {
-        return isNonExpansive(body.expression);
-      } else if (body is ast.Block) {
-        var link = body.statements.nodes;
-        if (link.isNotEmpty && link.tail.isEmpty) {
-          if (link.head is ast.Return) {
-            return isNonExpansive(link.head.expression);
-          } else if (link.head is ast.ExpressionStatement) {
-            return isNonExpansive(link.head.expression);
-          }
-        }
-      }
-      return false;
-    }
-
-    if (!shouldInline()) return null;
-
-    FunctionDefinition target = functionCompiler.compileToCpsIr(node.target);
-
-    CpsFragment cps = new CpsFragment(node.sourceInformation);
-    Primitive result = cps.inlineFunction(target,
-        null,
-        node.arguments.map((ref) => ref.definition).toList(),
-        hint: node.hint);
-    node.replaceUsesWith(result);
-    return cps;
-  }
-
   visitInvokeStatic(InvokeStatic node) {
-    return specializeInternalMethodCall(node) ?? inlineInvokeStatic(node);
+    return specializeInternalMethodCall(node);
   }
 
   AbstractConstantValue getValue(Variable node) {
@@ -2073,6 +2037,11 @@
         if (argumentsWereRemoved) {
           node.arguments.removeWhere((ref) => ref == null);
         }
+        if (node.arguments.length == 1) {
+          Primitive input = node.arguments[0].definition;
+          node.replaceUsesWith(input);
+          input.useElementAsHint(node.hint);
+        }
         // TODO(asgerf): Rebalance nested StringConcats that arise from
         //               rewriting the + operator to StringConcat.
         break;
@@ -2215,7 +2184,6 @@
     CpsFragment cps = new CpsFragment(node.sourceInformation);
     Interceptor interceptor =
         cps.letPrim(new Interceptor(prim, node.sourceInformation));
-    interceptor.interceptedClasses.addAll(backend.interceptedClasses);
     Primitive testViaFlag =
         cps.letPrim(new TypeTestViaFlag(interceptor, dartType));
     node.replaceUsesWith(testViaFlag);
@@ -2226,163 +2194,6 @@
     return null;
   }
 
-  Primitive visitInterceptor(Interceptor node) {
-    AbstractConstantValue value = getValue(node.input.definition);
-    TypeMask interceptedInputs = value.type.intersection(
-        typeSystem.interceptorType.nullable(), classWorld);
-    bool interceptNull =
-        node.interceptedClasses.contains(helpers.jsNullClass) ||
-        node.interceptedClasses.contains(helpers.jsInterceptorClass);
-
-    void filterInterceptedClasses() {
-      if (lattice.isDefinitelyInt(value, allowNull: !interceptNull)) {
-        node.interceptedClasses..clear()..add(helpers.jsIntClass);
-        return;
-      }
-      if (lattice.isDefinitelyNum(value, allowNull: !interceptNull) &&
-                  jsNumberClassSuffices(node)) {
-        node.interceptedClasses..clear()..add(helpers.jsNumberClass);
-        return;
-      }
-
-      // TODO(asgerf): Avoid adding non-instantiated intercepted classes
-      // in the first place.  (This should also happen in later pass).
-      node.interceptedClasses.retainWhere(classWorld.isInstantiated);
-
-      TypeMask interceptedClassesType = new TypeMask.unionOf(
-          node.interceptedClasses.map(typeSystem.getInterceptorSubtypes),
-          classWorld);
-      TypeMask interceptedAndCaught =
-          interceptedInputs.intersection(interceptedClassesType, classWorld);
-      ClassElement single = interceptedAndCaught.singleClass(classWorld);
-      if (single != null) {
-        node.interceptedClasses..clear()..add(backend.getRuntimeClass(single));
-        return;
-      }
-
-      // Filter out intercepted classes that do not match the input type.
-      node.interceptedClasses.retainWhere((ClassElement clazz) {
-        return !typeSystem.areDisjoint(
-            value.type,
-            typeSystem.getInterceptorSubtypes(clazz));
-      });
-
-      // The interceptor root class will usually not be filtered out because all
-      // intercepted values are subtypes of it.  But it can be "shadowed" by a
-      // more specific interceptor classes if all possible intercepted values
-      // will hit one of the more specific classes.
-      //
-      // For example, if all classes can respond to a given call, but we know
-      // the input is a string or an unknown JavaScript object, we want to
-      // use a specialized interceptor:
-      //
-      //   getInterceptor(x).get$hashCode(x);
-      //     ==>
-      //   getInterceptor$su(x).get$hashCode(x)
-      //
-      // In this case, the intercepted classes that were not filtered out above
-      // are {UnknownJavaScriptObject, JSString, Interceptor}, but there is no
-      // need to include the Interceptor class.
-      //
-      // We only do this optimization if the resulting interceptor call is
-      // sufficiently specialized to be worth it (#classes <= 2).
-      // TODO(asgerf): Reconsider when TypeTestViaFlag interceptors don't
-      //               intercept ALL interceptor classes.
-      if (node.interceptedClasses.length > 1 &&
-          node.interceptedClasses.length < 4 &&
-          node.interceptedClasses.contains(helpers.jsInterceptorClass)) {
-        TypeMask specificInterceptors = new TypeMask.unionOf(
-            node.interceptedClasses
-              .where((cl) => cl != helpers.jsInterceptorClass)
-              .map(typeSystem.getInterceptorSubtypes),
-            classWorld);
-        if (specificInterceptors.containsMask(interceptedInputs, classWorld)) {
-          // All possible inputs are caught by an Interceptor subclass (or are
-          // self-interceptors), so there is no need to have the check for
-          // the Interceptor root class (which is expensive).
-          node.interceptedClasses.remove(helpers.jsInterceptorClass);
-        }
-      }
-    }
-
-    filterInterceptedClasses();
-
-    // Remove the interceptor call if it can only return its input.
-    if (node.interceptedClasses.isEmpty) {
-      node.replaceUsesWith(node.input.definition);
-      return null;
-    }
-
-    node.flags = Interceptor.ALL_FLAGS;
-
-    // If there is only one caught interceptor class, determine more precisely
-    // how this might resolve at runtime.  Later optimizations depend on this,
-    // but do not have refined type information available.
-    if (node.interceptedClasses.length == 1) {
-      ClassElement class_ = node.interceptedClasses.single;
-      if (value.isDefinitelyNotNull) {
-        node.clearFlag(Interceptor.NULL);
-      } else if (interceptNull) {
-        node.clearFlag(Interceptor.NULL_BYPASS);
-        if (class_ == helpers.jsNullClass) {
-          node.clearFlag(Interceptor.NULL_INTERCEPT_SUBCLASS);
-        } else {
-          node.clearFlag(Interceptor.NULL_INTERCEPT_EXACT);
-        }
-      } else {
-        node.clearFlag(Interceptor.NULL_INTERCEPT);
-      }
-      if (typeSystem.isDefinitelyIntercepted(value.type, allowNull: true)) {
-        node.clearFlag(Interceptor.SELF_INTERCEPT);
-      }
-      TypeMask interceptedInputsNonNullable = interceptedInputs.nonNullable();
-      TypeMask interceptedType = typeSystem.getInterceptorSubtypes(class_);
-      if (interceptedType.containsMask(interceptedInputsNonNullable,
-              classWorld)) {
-        node.clearFlag(Interceptor.NON_NULL_BYPASS);
-      }
-      if (class_ == helpers.jsNumberClass) {
-        // See [jsNumberClassSuffices].  We know that JSInt and JSDouble are
-        // not intercepted classes so JSNumber is sufficient.
-        node.clearFlag(Interceptor.NON_NULL_INTERCEPT_SUBCLASS);
-      } else if (class_ == helpers.jsArrayClass) {
-        // JSArray has compile-time subclasses like JSFixedArray, but should
-        // still be considered "exact" if the input is any subclass of JSArray.
-        if (typeSystem.isDefinitelyArray(interceptedInputsNonNullable)) {
-          node.clearFlag(Interceptor.NON_NULL_INTERCEPT_SUBCLASS);
-        }
-      } else {
-        TypeMask exactInterceptedType = typeSystem.nonNullExact(class_);
-        if (exactInterceptedType.containsMask(interceptedInputsNonNullable,
-                classWorld)) {
-          node.clearFlag(Interceptor.NON_NULL_INTERCEPT_SUBCLASS);
-        }
-      }
-    }
-    return null;
-  }
-
-  bool jsNumberClassSuffices(Interceptor node) {
-    // No methods on JSNumber call 'down' to methods on JSInt or JSDouble.  If
-    // all uses of the interceptor are for methods is defined only on JSNumber
-    // then JSNumber will suffice in place of choosing between JSInt or
-    // JSDouble.
-    for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
-      if (ref.parent is InvokeMethod) {
-        InvokeMethod invoke = ref.parent;
-        if (invoke.receiver != ref) return false;
-        var interceptedClasses =
-            functionCompiler.glue.getInterceptedClassesOn(invoke.selector);
-        if (interceptedClasses.contains(helpers.jsDoubleClass)) return false;
-        if (interceptedClasses.contains(helpers.jsIntClass)) return false;
-        continue;
-      }
-      // Other uses need full distinction.
-      return false;
-    }
-    return true;
-  }
-
   visitBoundsCheck(BoundsCheck node) {
     // Eliminate bounds checks using constant folding.
     // The [BoundsChecker] pass does not try to eliminate checks that could be
@@ -2674,7 +2485,7 @@
   }
 
   void visitInvokeMethod(InvokeMethod node) {
-    AbstractConstantValue receiver = getValue(node.receiver.definition);
+    AbstractConstantValue receiver = getValue(node.dartReceiver);
     node.receiverIsNotNull = receiver.isDefinitelyNotNull;
     if (receiver.isNothing) {
       return setResult(node, lattice.nothing);
@@ -2683,7 +2494,7 @@
     void finish(AbstractConstantValue result, {bool canReplace: false}) {
       if (result == null) {
         canReplace = false;
-        result = lattice.getInvokeReturnType(node.selector, node.mask);
+        result = lattice.getInvokeReturnType(node.selector, receiver);
       }
       setResult(node, result, canReplace: canReplace);
     }
@@ -2691,10 +2502,9 @@
     if (node.selector.isGetter) {
       // Constant fold known length of containers.
       if (node.selector == Selectors.length) {
-        AbstractConstantValue object = getValue(node.dartReceiver);
-        if (typeSystem.isDefinitelyIndexable(object.type, allowNull: true)) {
-          AbstractConstantValue length = lattice.lengthSpecial(object);
-          return finish(length, canReplace: !object.isNullable);
+        if (typeSystem.isDefinitelyIndexable(receiver.type, allowNull: true)) {
+          AbstractConstantValue length = lattice.lengthSpecial(receiver);
+          return finish(length, canReplace: !receiver.isNullable);
         }
       }
       return finish(null);
@@ -2702,19 +2512,18 @@
 
     if (node.selector.isCall) {
       if (node.selector == Selectors.codeUnitAt) {
-        AbstractConstantValue object = getValue(node.dartReceiver);
         AbstractConstantValue right = getValue(node.dartArgument(0));
-        AbstractConstantValue result = lattice.codeUnitAtSpecial(object, right);
-        return finish(result, canReplace: !object.isNullable);
+        AbstractConstantValue result =
+            lattice.codeUnitAtSpecial(receiver, right);
+        return finish(result, canReplace: !receiver.isNullable);
       }
       return finish(null);
     }
 
     if (node.selector == Selectors.index) {
-      AbstractConstantValue object = getValue(node.dartReceiver);
       AbstractConstantValue right = getValue(node.dartArgument(0));
-      AbstractConstantValue result = lattice.indexSpecial(object, right);
-      return finish(result, canReplace: !object.isNullable);
+      AbstractConstantValue result = lattice.indexSpecial(receiver, right);
+      return finish(result, canReplace: !receiver.isNullable);
     }
 
     if (!node.selector.isOperator) {
@@ -2724,21 +2533,20 @@
     // Calculate the resulting constant if possible.
     String opname = node.selector.name;
     if (node.arguments.length == 1) {
-      AbstractConstantValue argument = getValue(node.dartReceiver);
       // Unary operator.
       if (opname == "unary-") {
         opname = "-";
       }
       UnaryOperator operator = UnaryOperator.parse(opname);
-      AbstractConstantValue result = lattice.unaryOp(operator, argument);
-      return finish(result, canReplace: !argument.isNullable);
+      AbstractConstantValue result = lattice.unaryOp(operator, receiver);
+      return finish(result, canReplace: !receiver.isNullable);
     } else if (node.arguments.length == 2) {
       // Binary operator.
-      AbstractConstantValue left = getValue(node.dartReceiver);
       AbstractConstantValue right = getValue(node.dartArgument(0));
       BinaryOperator operator = BinaryOperator.parse(opname);
-      AbstractConstantValue result = lattice.binaryOp(operator, left, right);
-      return finish(result, canReplace: !left.isNullable);
+      AbstractConstantValue result =
+          lattice.binaryOp(operator, receiver, right);
+      return finish(result, canReplace: !receiver.isNullable);
     }
     return finish(null);
   }
diff --git a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
index 0f4e624..90d4ecf 100644
--- a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
@@ -1777,6 +1777,23 @@
     'template': 'The library is imported here.',
   },
 
+  'MAIN_HAS_PART_OF': {
+    'id': 'MFMRRL',
+    'template': "The main application file must not have a 'part-of' "
+                "directive.",
+    'howToFix': "Try removing the 'part-of' directive or starting compilation "
+                "from another file.",
+    'examples': [
+      {
+        'main.dart': """
+part of library;
+
+main() {}
+"""
+      }
+    ],
+  },
+
   'LIBRARY_NAME_MISMATCH': {
     'id': 'AXGYPQ',
     'template': "Expected part of library name '#{libraryName}'.",
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index e651063..b529e1c 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -232,6 +232,7 @@
   LIBRARY_NOT_FOUND,
   LIBRARY_NOT_SUPPORTED,
   LIBRARY_TAG_MUST_BE_FIRST,
+  MAIN_HAS_PART_OF,
   MAIN_NOT_A_FUNCTION,
   MAIN_WITH_EXTRA_PARAMETER,
   MALFORMED_STRING_LITERAL,
@@ -662,6 +663,7 @@
   MessageKind.LIBRARY_NOT_FOUND: "LIBRARY_NOT_FOUND",
   MessageKind.LIBRARY_NOT_SUPPORTED: "LIBRARY_NOT_SUPPORTED",
   MessageKind.LIBRARY_TAG_MUST_BE_FIRST: "LIBRARY_TAG_MUST_BE_FIRST",
+  MessageKind.MAIN_HAS_PART_OF: "MAIN_HAS_PART_OF",
   MessageKind.MAIN_NOT_A_FUNCTION: "MAIN_NOT_A_FUNCTION",
   MessageKind.MAIN_WITH_EXTRA_PARAMETER: "MAIN_WITH_EXTRA_PARAMETER",
   MessageKind.MALFORMED_STRING_LITERAL: "MALFORMED_STRING_LITERAL",
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 5549f45..550b3c9 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -45,6 +45,12 @@
 import 'visitor.dart' show
     ElementVisitor;
 
+/// Object that identifies a declaration site.
+///
+/// For most elements, this is the element itself, but for variable declarations
+/// where multi-declarations like `var a, b, c` are allowed, the declaration
+/// site is a separate object.
+// TODO(johnniwinther): Add [beginToken] and [endToken] getters.
 abstract class DeclarationSite {
 }
 
@@ -2790,7 +2796,8 @@
   }
 }
 
-class EnumClassElementX extends ClassElementX implements EnumClassElement {
+class EnumClassElementX extends ClassElementX
+    implements EnumClassElement, DeclarationSite {
   final Enum node;
   List<FieldElement> _enumValues;
 
@@ -2827,6 +2834,9 @@
         message: "enumValues has already been computed for $this."));
     _enumValues = values;
   }
+
+  @override
+  DeclarationSite get declarationSite => this;
 }
 
 class EnumConstructorElementX extends ConstructorElementX {
@@ -2887,17 +2897,14 @@
   }
 }
 
-class MixinApplicationElementX extends BaseClassElementX
+abstract class MixinApplicationElementX extends BaseClassElementX
     implements MixinApplicationElement {
-  final Node node;
-  final Modifiers modifiers;
 
   Link<ConstructorElement> constructors = new Link<ConstructorElement>();
 
   InterfaceType mixinType;
 
-  MixinApplicationElementX(String name, Element enclosing, int id,
-                           this.node, this.modifiers)
+  MixinApplicationElementX(String name, Element enclosing, int id)
       : super(name, enclosing, id, STATE_NOT_STARTED);
 
   ClassElement get mixin => mixinType != null ? mixinType.element : null;
@@ -2974,6 +2981,35 @@
   }
 }
 
+class NamedMixinApplicationElementX extends MixinApplicationElementX
+    implements DeclarationSite {
+  final NamedMixinApplication node;
+
+  NamedMixinApplicationElementX(
+      String name,
+      CompilationUnitElement enclosing,
+      int id,
+      this.node)
+      : super(name, enclosing, id);
+
+  Modifiers get modifiers => node.modifiers;
+
+  DeclarationSite get declarationSite => this;
+}
+
+class UnnamedMixinApplicationElementX extends MixinApplicationElementX {
+  final Node node;
+
+  UnnamedMixinApplicationElementX(
+      String name,
+      CompilationUnitElement enclosing,
+      int id,
+      this.node)
+      : super(name, enclosing, id);
+
+  bool get isAbstract => true;
+}
+
 class LabelDefinitionX implements LabelDefinition {
   final Label label;
   final String labelName;
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 1a08cfb..3a9fd2e 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -162,4 +162,27 @@
 
   @override
   String get value => _literal.value;
-}
\ No newline at end of file
+}
+
+/// Returns `true` if [template] will immediately give a TypeError if the first
+/// placeholder is `null` or `undefined`.
+bool isNullGuardOnFirstArgument(Template template) {
+  // We look for a template of the form
+  //
+  //     #.something
+  //     #.something()
+  //
+  Node node = template.ast;
+  if (node is Call) {
+    Call call = node;
+    node = call.target;
+  }
+  if (node is PropertyAccess) {
+    PropertyAccess access = node;
+    if (access.receiver is InterpolatedExpression) {
+      InterpolatedExpression hole = access.receiver;
+      return hole.isPositional && hole.nameOrPosition == 0;
+    }
+  }
+  return false;
+}
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 54f2d40..bc8ed93 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -20,7 +20,8 @@
 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
 import '../../tree_ir/tree_ir_nodes.dart' show
     BuiltinMethod,
-    BuiltinOperator;
+    BuiltinOperator,
+    isCompoundableOperator;
 import '../../types/types.dart' show
     TypeMask;
 import '../../universe/call_structure.dart' show
@@ -80,7 +81,7 @@
   /// [Unreachable] statements whether they may use fallthrough or not.
   List<bool> emitUnreachableAsReturn = <bool>[false];
 
-  Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>();
+  final Map<tree_ir.Label, String> labelNames = <tree_ir.Label, String>{};
 
   List<js.Statement> accumulator = new List<js.Statement>();
 
@@ -505,11 +506,67 @@
     return new js.VariableUse(getVariableName(variable));
   }
 
+  /// Returns the JS operator for the given built-in operator for use in a
+  /// compound assignment (not including the '=' sign).
+  String getAsCompoundOperator(BuiltinOperator operator) {
+    switch (operator) {
+      case BuiltinOperator.NumAdd:
+      case BuiltinOperator.StringConcatenate:
+        return '+';
+      case BuiltinOperator.NumSubtract:
+        return '-';
+      case BuiltinOperator.NumMultiply:
+        return '*';
+      case BuiltinOperator.NumDivide:
+        return '/';
+      case BuiltinOperator.NumRemainder:
+        return '%';
+      default:
+        throw 'Not a compoundable operator: $operator';
+    }
+  }
+
+  bool isCompoundableBuiltin(tree_ir.Expression exp) {
+    return exp is tree_ir.ApplyBuiltinOperator &&
+           exp.arguments.length == 2 &&
+           isCompoundableOperator(exp.operator);
+  }
+
+  bool isOneConstant(tree_ir.Expression exp) {
+    return exp is tree_ir.Constant && exp.value.isOne;
+  }
+
+  js.Expression makeAssignment(
+      js.Expression leftHand,
+      tree_ir.Expression value,
+      {BuiltinOperator compound}) {
+    if (isOneConstant(value)) {
+      if (compound == BuiltinOperator.NumAdd) {
+        return new js.Prefix('++', leftHand);
+      }
+      if (compound == BuiltinOperator.NumSubtract) {
+        return new js.Prefix('--', leftHand);
+      }
+    }
+    if (compound != null) {
+      return new js.Assignment.compound(leftHand,
+          getAsCompoundOperator(compound), visitExpression(value));
+    }
+    return new js.Assignment(leftHand, visitExpression(value));
+  }
+
   @override
   js.Expression visitAssign(tree_ir.Assign node) {
-    return new js.Assignment(
-        buildVariableAccess(node.variable),
-        visitExpression(node.value));
+    js.Expression variable = buildVariableAccess(node.variable);
+    if (isCompoundableBuiltin(node.value)) {
+      tree_ir.ApplyBuiltinOperator rhs = node.value;
+      tree_ir.Expression left = rhs.arguments[0];
+      tree_ir.Expression right = rhs.arguments[1];
+      if (left is tree_ir.VariableUse && left.variable == node.variable) {
+        return makeAssignment(variable, right, compound: rhs.operator);
+      }
+    }
+    return makeAssignment(variable, node.value);
   }
 
   @override
@@ -524,8 +581,7 @@
       shortContinue.use();
       accumulator.add(new js.Continue(null));
     } else {
-      usedLabels.add(node.target);
-      accumulator.add(new js.Continue(node.target.name));
+      accumulator.add(new js.Continue(makeLabel(node.target)));
     }
   }
 
@@ -557,8 +613,7 @@
       shortContinue.use();
       accumulator.add(new js.Continue(null));
     } else {
-      usedLabels.add(node.target);
-      accumulator.add(new js.Break(node.target.name));
+      accumulator.add(new js.Break(makeLabel(node.target)));
     }
   }
 
@@ -613,13 +668,18 @@
     visitStatement(node.next);
   }
 
+  /// Creates a name for [label] if it does not already have one.
+  ///
+  /// This also marks the label as being used.
+  String makeLabel(tree_ir.Label label) {
+    return labelNames.putIfAbsent(label, () => 'L${labelNames.length}');
+  }
+
   /// Wraps a node in a labeled statement unless the label is unused.
   js.Statement insertLabel(tree_ir.Label label, js.Statement node) {
-    if (usedLabels.remove(label)) {
-      return new js.LabeledStatement(label.name, node);
-    } else {
-      return node;
-    }
+    String name = labelNames[label];
+    if (name == null) return node; // Label is unused.
+    return new js.LabeledStatement(name, node);
   }
 
   /// Returns the current [accumulator] wrapped in a block if neccessary.
@@ -729,11 +789,6 @@
   }
 
   @override
-  void visitRethrow(tree_ir.Rethrow node) {
-    glue.reportInternalError('rethrow seen in JavaScript output');
-  }
-
-  @override
   void visitUnreachable(tree_ir.Unreachable node) {
     if (emitUnreachableAsReturn.last) {
       // Emit a return to assist local analysis in the VM.
@@ -806,8 +861,13 @@
   @override
   js.Expression visitInterceptor(tree_ir.Interceptor node) {
     registry.registerUseInterceptor();
-    registry.registerSpecializedGetInterceptor(node.interceptedClasses);
-    js.Name helperName = glue.getInterceptorName(node.interceptedClasses);
+    // Default to all intercepted classes if they have not been computed.
+    // This is to ensure we can run codegen without prior optimization passes.
+    Set<ClassElement> interceptedClasses = node.interceptedClasses.isEmpty
+        ? glue.interceptedClasses
+        : node.interceptedClasses;
+    registry.registerSpecializedGetInterceptor(interceptedClasses);
+    js.Name helperName = glue.getInterceptorName(interceptedClasses);
     js.Expression globalHolder = glue.getInterceptorLibrary();
     return js.js('#.#(#)',
         [globalHolder, helperName, visitExpression(node.input)])
@@ -823,13 +883,13 @@
   }
 
   @override
-  js.Assignment visitSetField(tree_ir.SetField node) {
+  js.Expression visitSetField(tree_ir.SetField node) {
     registry.registerStaticUse(new StaticUse.fieldSet(node.field));
     js.PropertyAccess field =
         new js.PropertyAccess(
             visitExpression(node.object),
             glue.instanceFieldPropertyName(node.field));
-    return new js.Assignment(field, visitExpression(node.value));
+    return makeAssignment(field, node.value, compound: node.compound);
   }
 
   @override
@@ -879,10 +939,9 @@
 
   @override
   js.Expression visitSetIndex(tree_ir.SetIndex node) {
-    return js.js('#[#] = #',
-        [visitExpression(node.object),
-         visitExpression(node.index),
-         visitExpression(node.value)]);
+    js.Expression index = new js.PropertyAccess(
+        visitExpression(node.object), visitExpression(node.index));
+    return makeAssignment(index, node.value, compound: node.compound);
   }
 
   js.Expression buildStaticHelperInvocation(
@@ -965,7 +1024,15 @@
   @override
   void visitNullCheck(tree_ir.NullCheck node) {
     js.Expression value = visitExpression(node.value);
-    js.Expression access = node.selector != null
+    // TODO(sra): Try to use the selector even when [useSelector] is false. The
+    // reason we use 'toString' is that it is always defined so avoids a slow
+    // lookup (in V8) of an absent property. We could use the property for the
+    // selector if we knew it was present. The property is present if the
+    // associated method was not inlined away, or if there is a noSuchMethod
+    // hook for that selector. We don't know these things here, but the decision
+    // could be deferred by creating a deferred property that was resolved after
+    // codegen.
+    js.Expression access = node.selector != null && node.useSelector
         ? js.js('#.#', [value, glue.invocationName(node.selector)])
         : js.js('#.toString', [value]);
     if (node.condition != null) {
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 33430be..034dd10 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -224,13 +224,14 @@
       applyCpsPass(new GVN(compiler, typeSystem), cpsFunction);
       applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
       applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
+      applyCpsPass(new LoopInvariantBranchMotion(), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new ScalarReplacer(compiler), cpsFunction);
       applyCpsPass(new MutableVariableEliminator(), cpsFunction);
       applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
       applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
-      applyCpsPass(new OptimizeInterceptors(backend), cpsFunction);
+      applyCpsPass(new OptimizeInterceptors(backend, typeSystem), cpsFunction);
       applyCpsPass(new BackwardNullCheckRemover(typeSystem), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
     });
diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
index f1f5dd0..2596b91 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
@@ -2,7 +2,7 @@
 
 import '../../cps_ir/cps_ir_nodes.dart';
 
-import '../../cps_ir/optimizers.dart' show ParentVisitor, Pass;
+import '../../cps_ir/optimizers.dart' show Pass;
 import '../../constants/values.dart';
 import '../../elements/elements.dart';
 import '../../js_backend/codegen/glue.dart';
@@ -219,8 +219,7 @@
       //  Change 'receiver.foo()'  to  'this.foo(receiver)'.
       newReceiver = thisParameter;
     } else {
-      newReceiver = new Interceptor(receiver, node.sourceInformation)
-          ..interceptedClasses.addAll(_glue.getInterceptedClassesOn(selector));
+      newReceiver = new Interceptor(receiver, node.sourceInformation);
       if (receiver.hint != null) {
         newReceiver.hint = new InterceptorEntity(receiver.hint);
       }
@@ -234,7 +233,6 @@
   processInvokeMethodDirectly(InvokeMethodDirectly node) {
     if (!_glue.isInterceptedMethod(node.target)) return;
 
-    Selector selector = node.selector;
     Primitive receiver = node.receiver.definition;
     Primitive newReceiver;
 
@@ -244,8 +242,7 @@
       //  Change 'receiver.foo()'  to  'this.foo(receiver)'.
       newReceiver = thisParameter;
     } else {
-      newReceiver = new Interceptor(receiver, node.sourceInformation)
-        ..interceptedClasses.addAll(_glue.getInterceptedClassesOn(selector));
+      newReceiver = new Interceptor(receiver, node.sourceInformation);
       if (receiver.hint != null) {
         newReceiver.hint = new InterceptorEntity(receiver.hint);
       }
@@ -255,8 +252,4 @@
     node.receiver = new Reference<Primitive>(newReceiver)..parent = node;
     node.callingConvention = CallingConvention.Intercepted;
   }
-
-  processInterceptor(Interceptor node) {
-    _glue.registerSpecializedGetInterceptor(node.interceptedClasses);
-  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 11a80a4..290d563 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -191,6 +191,7 @@
   final greaterEqual = const GreaterEqualOperation();
   final greater = const GreaterOperation();
   final identity = const JavaScriptIdentityOperation();
+  final ifNull = const IfNullOperation();
   final lessEqual = const LessEqualOperation();
   final less = const LessOperation();
   final modulo =
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index b16379f..fb34fae 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -674,56 +674,66 @@
     return new jsAst.Block(parts);
   }
 
-  jsAst.Statement buildLazilyInitializedStaticFields() {
-    JavaScriptConstantCompiler handler = backend.constants;
-    List<VariableElement> lazyFields =
-        handler.getLazilyInitializedFieldsForEmission();
+  jsAst.Statement buildLazilyInitializedStaticFields(
+      Iterable<StaticField> lazyFields, {bool isMainFragment: true}) {
     if (lazyFields.isNotEmpty) {
       needsLazyInitializer = true;
-      List<jsAst.Expression> laziesInfo = buildLaziesInfo(lazyFields);
+      List<jsAst.Expression> laziesInfo =
+          buildLaziesInfo(lazyFields, isMainFragment);
       return js.statement('''
       (function(lazies) {
         for (var i = 0; i < lazies.length; ) {
           var fieldName = lazies[i++];
           var getterName = lazies[i++];
+          var lazyValue = lazies[i++];
           if (#notMinified) {
             var staticName = lazies[i++];
           }
-          var lazyValue = lazies[i++];
-
+          if (#isDeferredFragment) {
+            var fieldHolder = lazies[i++];
+          }
           // We build the lazy-check here:
           //   lazyInitializer(fieldName, getterName, lazyValue, staticName);
           // 'staticName' is used for error reporting in non-minified mode.
           // 'lazyValue' must be a closure that constructs the initial value.
-          if (#notMinified) {
-            #lazy(fieldName, getterName, lazyValue, staticName);
+          if (#isMainFragment) {
+            if (#notMinified) {
+              #lazy(fieldName, getterName, lazyValue, staticName);
+            } else {
+              #lazy(fieldName, getterName, lazyValue);
+            }
           } else {
-            #lazy(fieldName, getterName, lazyValue);
+            if (#notMinified) {
+              #lazy(fieldName, getterName, lazyValue, staticName, fieldHolder);
+            } else {
+              #lazy(fieldName, getterName, lazyValue, null, fieldHolder);
+            }
           }
         }
       })(#laziesInfo)
       ''', {'notMinified': !compiler.enableMinification,
             'laziesInfo': new jsAst.ArrayInitializer(laziesInfo),
-            'lazy': js(lazyInitializerName)});
+            'lazy': js(lazyInitializerName),
+            'isMainFragment': isMainFragment,
+            'isDeferredFragment': !isMainFragment});
     } else {
       return js.comment("No lazy statics.");
     }
   }
 
-  List<jsAst.Expression> buildLaziesInfo(List<VariableElement> lazies) {
+  List<jsAst.Expression> buildLaziesInfo(
+      Iterable<StaticField> lazies, bool isMainFragment) {
     List<jsAst.Expression> laziesInfo = <jsAst.Expression>[];
-    for (VariableElement element in Elements.sortedByPosition(lazies)) {
-      jsAst.Expression code = backend.generatedCode[element];
-      // The code is null if we ended up not needing the lazily
-      // initialized field after all because of constant folding
-      // before code generation.
-      if (code == null) continue;
-      laziesInfo.add(js.quoteName(namer.globalPropertyName(element)));
-      laziesInfo.add(js.quoteName(namer.lazyInitializerName(element)));
+    for (StaticField field in lazies) {
+      laziesInfo.add(js.quoteName(field.name));
+      laziesInfo.add(js.quoteName(namer.deriveLazyInitializerName(field.name)));
+      laziesInfo.add(field.code);
       if (!compiler.enableMinification) {
-        laziesInfo.add(js.string(element.name));
+        laziesInfo.add(js.quoteName(field.name));
       }
-      laziesInfo.add(code);
+      if (!isMainFragment) {
+        laziesInfo.add(js('#', field.holder.name));
+      }
     }
     return laziesInfo;
   }
@@ -1570,7 +1580,8 @@
           mainOutputUnit),
       "typeToInterceptorMap":
           interceptorEmitter.buildTypeToInterceptorMap(program),
-      "lazyStaticFields": buildLazilyInitializedStaticFields(),
+      "lazyStaticFields": buildLazilyInitializedStaticFields(
+          mainFragment.staticLazilyInitializedFields),
       "metadata": buildMetadata(program, mainOutputUnit),
       "convertToFastObject": buildConvertToFastObjectFunction(),
       "convertToSlowObject": buildConvertToSlowObjectFunction(),
@@ -1996,6 +2007,8 @@
       body.add(buildCompileTimeConstants(fragment.constants,
                                          isMainFragment: false));
       body.add(buildStaticNonFinalFieldInitializations(outputUnit));
+      body.add(buildLazilyInitializedStaticFields(
+          fragment.staticLazilyInitializedFields, isMainFragment: false));
 
       List<jsAst.Statement> statements = <jsAst.Statement>[];
 
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 9471cac..42f7138 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -310,15 +310,12 @@
 
   List<StaticField> _buildStaticLazilyInitializedFields(
       LibrariesMap librariesMap) {
-    // TODO(floitsch): lazy fields should just be in their respective
-    // libraries.
-    if (librariesMap != _registry.mainLibrariesMap) {
-      return const <StaticField>[];
-    }
-
     JavaScriptConstantCompiler handler = backend.constants;
-    List<VariableElement> lazyFields =
-        handler.getLazilyInitializedFieldsForEmission();
+    DeferredLoadTask loadTask = _compiler.deferredLoadTask;
+    Iterable<VariableElement> lazyFields = handler
+        .getLazilyInitializedFieldsForEmission()
+        .where((element) =>
+            loadTask.outputUnitForElement(element) == librariesMap.outputUnit);
     return Elements.sortedByPosition(lazyFields)
         .map(_buildLazyField)
         .where((field) => field != null)  // Happens when the field was unused.
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 6defd7d..238d393 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -147,7 +147,13 @@
   /// [LibraryElement] for the library and computes the import/export scope,
   /// loading and computing the import/export scopes of all required libraries
   /// in the process. The method handles cyclic dependency between libraries.
-  Future<LibraryElement> loadLibrary(Uri resolvedUri);
+  ///
+  /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the
+  /// compilation unit for [resolvedUri] contains a `part of` tag. This is only
+  /// used for analysis through [Compiler.analyzeUri].
+  Future<LibraryElement> loadLibrary(
+      Uri resolvedUri,
+      {bool skipFileWithPartOfTag: false});
 
   /// Reset the library loader task to prepare for compilation. If provided,
   /// libraries matching [reuseLibrary] are reused.
@@ -339,18 +345,27 @@
     Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
     libraryResourceUriMap[resourceUri] = library;
 
-    String name = library.libraryOrScriptName;
-    libraryNames[name] = library;
+    if (library.hasLibraryName) {
+      String name = library.libraryName;
+      libraryNames[name] = library;
+    }
   }
 
-  Future<LibraryElement> loadLibrary(Uri resolvedUri) {
+  Future<LibraryElement> loadLibrary(
+      Uri resolvedUri,
+      {bool skipFileWithPartOfTag: false}) {
     return measure(() {
       assert(currentHandler == null);
       // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
       // loading of a library cluster.
       currentHandler = new LibraryDependencyHandler(this);
-      return createLibrary(currentHandler, null, resolvedUri)
+      return createLibrary(currentHandler, null, resolvedUri,
+          skipFileWithPartOfTag: skipFileWithPartOfTag)
           .then((LibraryElement library) {
+        if (library == null) {
+          currentHandler = null;
+          return null;
+        }
         return reporter.withCurrentElement(library, () {
           return measure(() {
             currentHandler.computeExports();
@@ -506,7 +521,7 @@
              'canonicalUri2': existing.canonicalUri});
       }
     } else if (library.hasLibraryName) {
-      String name = library.libraryOrScriptName;
+      String name = library.libraryName;
       existing = libraryNames.putIfAbsent(name, () => library);
       if (!identical(existing, library)) {
         reporter.withCurrentElement(library, () {
@@ -563,7 +578,7 @@
       LibraryDependencyElementX libraryDependency) {
     Uri base = library.canonicalUri;
     Uri resolvedUri = base.resolveUri(libraryDependency.uri);
-    return createLibrary(handler, library, resolvedUri, libraryDependency)
+    return createLibrary(handler, library, resolvedUri, node: libraryDependency)
         .then((LibraryElement loadedLibrary) {
           if (loadedLibrary == null) return;
           reporter.withCurrentElement(library, () {
@@ -600,10 +615,12 @@
    *
    * If a new library is created, the [handler] is notified.
    */
-  Future<LibraryElement> createLibrary(LibraryDependencyHandler handler,
-                                       LibraryElement importingLibrary,
-                                       Uri resolvedUri,
-                                       [Spannable node]) {
+  Future<LibraryElement> createLibrary(
+      LibraryDependencyHandler handler,
+      LibraryElement importingLibrary,
+      Uri resolvedUri,
+      {Spannable node,
+       bool skipFileWithPartOfTag: false}) {
     Uri readableUri =
         compiler.translateResolvedUri(importingLibrary, resolvedUri, node);
     LibraryElement library = libraryCanonicalUriMap[resolvedUri];
@@ -626,16 +643,30 @@
             createLibrarySync(handler, script, resolvedUri);
         CompilationUnitElementX compilationUnit = element.entryCompilationUnit;
         if (compilationUnit.partTag != null) {
-          DiagnosticMessage error = reporter.withCurrentElement(
-              compilationUnit,
-              () => reporter.createMessage(
-                  compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
-          DiagnosticMessage info = reporter.withCurrentElement(
-              importingLibrary,
-              () => reporter.createMessage(
-                  node,
-                  MessageKind.IMPORT_PART_OF_HERE));
-          reporter.reportError(error, <DiagnosticMessage>[info]);
+          if (skipFileWithPartOfTag) {
+            // TODO(johnniwinther): Avoid calling [Compiler.onLibraryCreated]
+            // for this library.
+            libraryCanonicalUriMap.remove(resolvedUri);
+            return null;
+          }
+          if (importingLibrary == null) {
+            DiagnosticMessage error = reporter.withCurrentElement(
+                compilationUnit,
+                () => reporter.createMessage(
+                    compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF));
+            reporter.reportError(error);
+          } else {
+            DiagnosticMessage error = reporter.withCurrentElement(
+                compilationUnit,
+                () => reporter.createMessage(
+                    compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
+            DiagnosticMessage info = reporter.withCurrentElement(
+                importingLibrary,
+                () => reporter.createMessage(
+                    node,
+                    MessageKind.IMPORT_PART_OF_HERE));
+            reporter.reportError(error, [info]);
+          }
         }
         return processLibraryTags(handler, element).then((_) {
           reporter.withCurrentElement(element, () {
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index fb5314e..48bfae31 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -18,7 +18,7 @@
     EnumClassElementX,
     FieldElementX,
     LibraryElementX,
-    MixinApplicationElementX,
+    NamedMixinApplicationElementX,
     VariableList;
 import '../native/native.dart' as native;
 import '../string_validator.dart' show
@@ -301,9 +301,8 @@
 
     int id = idGenerator();
     Element enclosing = compilationUnitElement;
-    pushElement(new MixinApplicationElementX(name.source, enclosing, id,
-                                             namedMixinApplication,
-                                             modifiers));
+    pushElement(new NamedMixinApplicationElementX(
+        name.source, enclosing, id, namedMixinApplication));
     rejectBuiltInIdentifier(name);
   }
 
@@ -626,7 +625,9 @@
     reportFatalError(node, message);
   }
 
-  void pushElement(Element element) {
+  void pushElement(ElementX element) {
+    assert(invariant(element, element.declarationSite != null,
+        message: 'Missing declaration site for $element.'));
     popMetadata(element);
     compilationUnitElement.addMember(element, reporter);
   }
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index 64fb6a7..f46b9fdc 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -19,7 +19,8 @@
     ErroneousElementX,
     MixinApplicationElementX,
     SynthesizedConstructorElementX,
-    TypeVariableElementX;
+    TypeVariableElementX,
+    UnnamedMixinApplicationElementX;
 import '../ordered_typeset.dart' show
     OrderedTypeSet,
     OrderedTypeSetBuilder;
@@ -324,12 +325,12 @@
   DartType applyMixin(DartType supertype, DartType mixinType, Node node) {
     String superName = supertype.name;
     String mixinName = mixinType.name;
-    MixinApplicationElementX mixinApplication = new MixinApplicationElementX(
-        "${superName}+${mixinName}",
-        element.compilationUnit,
-        compiler.getNextFreeClassId(),
-        node,
-        new Modifiers.withFlags(new NodeList.empty(), Modifiers.FLAG_ABSTRACT));
+    MixinApplicationElementX mixinApplication =
+        new UnnamedMixinApplicationElementX(
+          "${superName}+${mixinName}",
+          element.compilationUnit,
+          compiler.getNextFreeClassId(),
+          node);
     // Create synthetic type variables for the mixin application.
     List<DartType> typeVariables = <DartType>[];
     int index = 0;
@@ -379,9 +380,10 @@
     return constructor;
   }
 
-  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
-                      DartType supertype,
-                      DartType mixinType) {
+  void doApplyMixinTo(
+      MixinApplicationElementX mixinApplication,
+      DartType supertype,
+      DartType mixinType) {
     Node node = mixinApplication.parseNode(resolution.parsing);
 
     if (mixinApplication.supertype != null) {
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 5fc06e1..b3c7686 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -36,7 +36,10 @@
     TypeUse;
 import '../universe/world_impact.dart' show
     WorldImpactBuilder;
-import '../world.dart' show World;
+import '../util/enumset.dart' show
+    EnumSet;
+import '../world.dart' show
+    World;
 
 import 'send_structure.dart';
 
@@ -47,7 +50,7 @@
 
 class _ResolutionWorldImpact extends ResolutionImpact with WorldImpactBuilder {
   final String name;
-  Setlet<Feature> _features;
+  EnumSet<Feature> _features;
   Setlet<MapLiteralUse> _mapLiterals;
   Setlet<ListLiteralUse> _listLiterals;
   Setlet<String> _constSymbolNames;
@@ -98,14 +101,15 @@
 
   void registerFeature(Feature feature) {
     if (_features == null) {
-      _features = new Setlet<Feature>();
+      _features = new EnumSet<Feature>();
     }
     _features.add(feature);
   }
 
   @override
   Iterable<Feature> get features {
-    return _features != null ? _features : const <Feature>[];
+    return _features != null
+        ? _features.iterable(Feature.values) : const <Feature>[];
   }
 
   void registerConstantLiteral(ConstantExpression constant) {
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 32b508f..f23533c 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -167,7 +167,7 @@
 
   /// Binding environment for variables that are assigned to effectively
   /// constant expressions (see [isEffectivelyConstant]).
-  Map<Variable, Expression> constantEnvironment;
+  Map<Variable, Expression> constantEnvironment = <Variable, Expression>{};
 
   /// Substitution map for labels. Any break to a label L should be substituted
   /// for a break to L' if L maps to L'.
@@ -186,14 +186,6 @@
   /// variable might have changed since it was put in the environment.
   final Map<Variable, int> dominatingAssignments = <Variable, int>{};
 
-  /// Rewriter for methods.
-  StatementRewriter() : constantEnvironment = <Variable, Expression>{};
-
-  /// Rewriter for nested functions.
-  StatementRewriter.nested(StatementRewriter parent)
-      : constantEnvironment = parent.constantEnvironment,
-        unseenUses = parent.unseenUses;
-
   /// A set of labels that can be safely inlined at their use.
   ///
   /// The successor statements for labeled statements that have only one break
@@ -202,6 +194,13 @@
   /// handler (i.e., if the code would be moved into a try from outside it).
   Set<Label> safeForInlining = new Set<Label>();
 
+  /// If the top element is true, assignments of form "x = CONST" may be
+  /// propagated into a following occurence of CONST.  This may confuse the JS
+  /// engine so it is disabled in some cases.
+  final List<bool> allowRhsPropagation = <bool>[true];
+
+  bool get isRhsPropagationAllowed => allowRhsPropagation.last;
+
   /// Returns the redirect target of [jump] or [jump] itself if it should not
   /// be redirected.
   Jump redirect(Jump jump) {
@@ -327,7 +326,8 @@
       //
       //     { E.foo = x; bar(x) } ==> bar(E.foo = x)
       //
-      if (getRightHandVariable(binding) == node.variable) {
+      if (isRhsPropagationAllowed &&
+          getRightHandVariable(binding) == node.variable) {
         environment.removeLast();
         --node.variable.readCount;
         return visitExpression(binding);
@@ -467,7 +467,9 @@
   }
 
   Expression visitAssign(Assign node) {
+    allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    allowRhsPropagation.removeLast();
     // Remove assignments to variables without any uses. This can happen
     // because the assignment was propagated into its use, e.g:
     //
@@ -482,10 +484,12 @@
 
   /// Process nodes right-to-left, the opposite of evaluation order in the case
   /// of argument lists..
-  void _rewriteList(List<Node> nodes) {
+  void _rewriteList(List<Node> nodes, {bool rhsPropagation: true}) {
+    allowRhsPropagation.add(rhsPropagation);
     for (int i = nodes.length - 1; i >= 0; --i) {
       nodes[i] = visitExpression(nodes[i]);
     }
+    allowRhsPropagation.removeLast();
   }
 
   Expression visitInvokeStatic(InvokeStatic node) {
@@ -607,10 +611,6 @@
     return node;
   }
 
-  Statement visitRethrow(Rethrow node) {
-    return node;
-  }
-
   Statement visitUnreachable(Unreachable node) {
     return node;
   }
@@ -721,7 +721,7 @@
   }
 
   Expression visitConstant(Constant node) {
-    if (!environment.isEmpty) {
+    if (isRhsPropagationAllowed && !environment.isEmpty) {
       Constant constant = getRightHandConstant(environment.last);
       if (constant != null && constant.value == node.value) {
         return visitExpression(environment.removeLast());
@@ -754,9 +754,37 @@
     return node;
   }
 
+  bool sameVariable(Expression e1, Expression e2) {
+    return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
+  }
+
+  bool isCompoundableBuiltin(Expression e) {
+    return e is ApplyBuiltinOperator &&
+           e.arguments.length == 2 &&
+           isCompoundableOperator(e.operator);
+  }
+
+  void destroyVariableUse(VariableUse node) {
+    --node.variable.readCount;
+  }
+
   Expression visitSetField(SetField node) {
+    allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    if (isCompoundableBuiltin(node.value)) {
+      ApplyBuiltinOperator rhs = node.value;
+      Expression left = rhs.arguments[0];
+      Expression right = rhs.arguments[1];
+      if (left is GetField &&
+          left.field == node.field &&
+          sameVariable(left.object, node.object)) {
+        destroyVariableUse(left.object);
+        node.compound = rhs.operator;
+        node.value = right;
+      }
+    }
     node.object = visitExpression(node.object);
+    allowRhsPropagation.removeLast();
     return node;
   }
 
@@ -770,7 +798,9 @@
   }
 
   Expression visitSetStatic(SetStatic node) {
+    allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    allowRhsPropagation.removeLast();
     return node;
   }
 
@@ -826,6 +856,19 @@
 
   Expression visitSetIndex(SetIndex node) {
     node.value = visitExpression(node.value);
+    if (isCompoundableBuiltin(node.value)) {
+      ApplyBuiltinOperator rhs = node.value;
+      Expression left = rhs.arguments[0];
+      Expression right = rhs.arguments[1];
+      if (left is GetIndex &&
+          sameVariable(left.object, node.object) &&
+          sameVariable(left.index, node.index)) {
+        destroyVariableUse(left.object);
+        destroyVariableUse(left.index);
+        node.compound = rhs.operator;
+        node.value = right;
+      }
+    }
     node.index = visitExpression(node.index);
     node.object = visitExpression(node.object);
     return node;
@@ -880,31 +923,31 @@
   /// foo() must be evaluated before bar(), so the propagation is only possible
   /// by commuting the operator.
   Expression visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    if (environment.isEmpty || getLeftHand(environment.last) == null) {
-      // If there is no recent assignment that might propagate, so there is no
-      // opportunity for optimization here.
-      _rewriteList(node.arguments);
-      return node;
-    }
-    Variable propagatableVariable = getLeftHand(environment.last);
-    BuiltinOperator commuted = commuteBinaryOperator(node.operator);
-    if (commuted != null) {
-      assert(node.arguments.length == 2); // Only binary operators can commute.
-      Expression left = node.arguments[0];
-      if (left is VariableUse && propagatableVariable == left.variable) {
-        Expression right = node.arguments[1];
-        if (right is This ||
-            (right is VariableUse &&
-             propagatableVariable != right.variable &&
-             !constantEnvironment.containsKey(right.variable))) {
-          // An assignment can be propagated if we commute the operator.
-          node.operator = commuted;
-          node.arguments[0] = right;
-          node.arguments[1] = left;
+    if (!environment.isEmpty && getLeftHand(environment.last) != null) {
+      Variable propagatableVariable = getLeftHand(environment.last);
+      BuiltinOperator commuted = commuteBinaryOperator(node.operator);
+      if (commuted != null) {
+        // Only binary operators can commute.
+        assert(node.arguments.length == 2);
+        Expression left = node.arguments[0];
+        if (left is VariableUse && propagatableVariable == left.variable) {
+          Expression right = node.arguments[1];
+          if (right is This ||
+              (right is VariableUse &&
+               propagatableVariable != right.variable &&
+               !constantEnvironment.containsKey(right.variable))) {
+            // An assignment can be propagated if we commute the operator.
+            node.operator = commuted;
+            node.arguments[0] = right;
+            node.arguments[1] = left;
+          }
         }
       }
     }
-    _rewriteList(node.arguments);
+    // Avoid code like `p == (q.f = null)`. JS operators with a constant operand
+    // can sometimes be compiled to a specialized instruction in the JS engine,
+    // so retain syntactically constant operands.
+    _rewriteList(node.arguments, rhsPropagation: false);
     return node;
   }
 
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 6c4297e..b846c87 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -410,10 +410,6 @@
     return new Throw(value);
   }
 
-  Statement visitRethrow(cps_ir.Rethrow node) {
-    return new Rethrow();
-  }
-
   Statement visitUnreachable(cps_ir.Unreachable node) {
     return new Unreachable();
   }
@@ -718,6 +714,7 @@
         condition: getVariableUseOrNull(node.condition),
         value: getVariableUse(node.value),
         selector: node.selector,
+        useSelector: node.useSelector,
         next: next,
         sourceInformation: node.sourceInformation);
   };
@@ -743,11 +740,6 @@
     return (Statement next) => next; // Compile to nothing.
   }
 
-  @override
-  Expression visitBoundsCheck(cps_ir.BoundsCheck node) {
-    throw 'Unexpected BoundsCheck node in tree builder';
-  }
-
   /********** UNUSED VISIT METHODS *************/
 
   unexpectedNode(cps_ir.Node node) {
@@ -760,4 +752,6 @@
   visitParameter(cps_ir.Parameter node) => unexpectedNode(node);
   visitContinuation(cps_ir.Continuation node) => unexpectedNode(node);
   visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node);
+  visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node);
+  visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node);
 }
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 215cf3a..19eeb05 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -67,18 +67,6 @@
  * Labels name [LabeledStatement]s.
  */
 class Label {
-  // A counter used to generate names.  The counter is reset to 0 for each
-  // function emitted.
-  static int counter = 0;
-  static String _newName() => 'L${counter++}';
-
-  String cachedName;
-
-  String get name {
-    if (cachedName == null) cachedName = _newName();
-    return cachedName;
-  }
-
   /// Number of [Break] or [Continue] statements that target this label.
   /// The [Break] constructor will increment this automatically, but the
   /// counter must be decremented by hand when a [Break] becomes orphaned.
@@ -619,21 +607,6 @@
   accept1(StatementVisitor1 visitor, arg) => visitor.visitThrow(this, arg);
 }
 
-/// A rethrow of an exception.
-///
-/// Rethrow can only occur nested inside a catch block.  It implicitly throws
-/// the block's caught exception value without changing the caught stack
-/// trace.  It does not have a successor statement.
-class Rethrow extends Statement {
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Rethrow();
-
-  accept(StatementVisitor visitor) => visitor.visitRethrow(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitRethrow(this, arg);
-}
-
 /**
  * A conditional branch based on the true value of an [Expression].
  */
@@ -743,7 +716,11 @@
   Element field;
   Expression value;
 
-  SetField(this.object, this.field, this.value);
+  /// If non-null, this is a compound assignment to the field, using the given
+  /// operator.  The operator must be a compoundable operator.
+  BuiltinOperator compound;
+
+  SetField(this.object, this.field, this.value, {this.compound});
 
   accept(ExpressionVisitor visitor) => visitor.visitSetField(this);
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
@@ -813,8 +790,9 @@
   Expression object;
   Expression index;
   Expression value;
+  BuiltinOperator compound;
 
-  SetIndex(this.object, this.index, this.value);
+  SetIndex(this.object, this.index, this.value, {this.compound});
 
   accept(ExpressionVisitor v) => v.visitSetIndex(this);
   accept1(ExpressionVisitor1 v, arg) => v.visitSetIndex(this, arg);
@@ -990,11 +968,12 @@
   Expression condition;
   Expression value;
   Selector selector;
+  bool useSelector;
   Statement next;
   SourceInformation sourceInformation;
 
-  NullCheck({this.condition, this.value, this.selector, this.next,
-      this.sourceInformation});
+  NullCheck({this.condition, this.value, this.selector, this.useSelector,
+      this.next, this.sourceInformation});
 
   accept(StatementVisitor visitor) {
     return visitor.visitNullCheck(this);
@@ -1086,7 +1065,6 @@
   S visitLabeledStatement(LabeledStatement node);
   S visitReturn(Return node);
   S visitThrow(Throw node);
-  S visitRethrow(Rethrow node);
   S visitBreak(Break node);
   S visitContinue(Continue node);
   S visitIf(If node);
@@ -1105,7 +1083,6 @@
   S visitLabeledStatement(LabeledStatement node, A arg);
   S visitReturn(Return node, A arg);
   S visitThrow(Throw node, A arg);
-  S visitRethrow(Rethrow node, A arg);
   S visitBreak(Break node, A arg);
   S visitContinue(Continue node, A arg);
   S visitIf(If node, A arg);
@@ -1204,8 +1181,6 @@
     visitExpression(node.value);
   }
 
-  visitRethrow(Rethrow node) {}
-
   visitBreak(Break node) {}
 
   visitContinue(Continue node) {}
@@ -1445,8 +1420,6 @@
     return node;
   }
 
-  visitRethrow(Rethrow node) => node;
-
   visitBreak(Break node) => node;
 
   visitContinue(Continue node) => node;
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index f43f287..979647a 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -82,10 +82,6 @@
     _addStatement(node);
   }
 
-  visitRethrow(Rethrow node) {
-    _addStatement(node);
-  }
-
   visitUnreachable(Unreachable node) {
     _addStatement(node);
   }
@@ -276,10 +272,6 @@
     printStatement(null, "throw ${expr(node.value)}");
   }
 
-  visitRethrow(Rethrow node) {
-    printStatement(null, "rethrow");
-  }
-
   visitUnreachable(Unreachable node) {
     printStatement(null, "unreachable");
   }
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index ac856a2..d895de2 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -4,9 +4,21 @@
 
 library dart2js.world.class_set;
 
-import 'dart:collection' show IterableBase;
-import '../elements/elements.dart' show ClassElement;
-import '../util/util.dart' show Link;
+import 'dart:collection' show
+    IterableBase;
+import '../elements/elements.dart' show
+    ClassElement;
+import '../util/enumset.dart' show
+    EnumSet;
+import '../util/util.dart' show
+    Link;
+
+/// Enum for the different kinds of instantiation of a class.
+enum Instantiation {
+  UNINSTANTIATED,
+  DIRECTLY_INSTANTIATED,
+  INDIRECTLY_INSTANTIATED,
+}
 
 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s.
 ///
@@ -34,7 +46,57 @@
 ///       E
 ///
 class ClassHierarchyNode {
+  /// Enum set for selecting instantiated classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static final EnumSet<Instantiation> INSTANTIATED =
+      new EnumSet<Instantiation>.fromValues(
+          const <Instantiation>[
+              Instantiation.DIRECTLY_INSTANTIATED,
+              Instantiation.INDIRECTLY_INSTANTIATED],
+          fixed: true);
+
+  /// Enum set for selecting directly instantiated classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED =
+      new EnumSet<Instantiation>.fromValues(
+          const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED],
+          fixed: true);
+
+  /// Enum set for selecting all classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static final EnumSet<Instantiation> ALL =
+      new EnumSet<Instantiation>.fromValues(
+          Instantiation.values,
+          fixed: true);
+
+  /// Creates an enum set for selecting the returned classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static EnumSet<Instantiation> createMask(
+      {bool includeDirectlyInstantiated: true,
+       bool includeIndirectlyInstantiated: true,
+       bool includeUninstantiated: true}) {
+    EnumSet<Instantiation> mask = new EnumSet<Instantiation>();
+    if (includeDirectlyInstantiated) {
+      mask.add(Instantiation.DIRECTLY_INSTANTIATED);
+    }
+    if (includeIndirectlyInstantiated) {
+      mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
+    }
+    if (includeUninstantiated) {
+      mask.add(Instantiation.UNINSTANTIATED);
+    }
+    return mask;
+  }
+
   final ClassElement cls;
+  final EnumSet<Instantiation> _mask =
+      new EnumSet<Instantiation>.fromValues(
+          const <Instantiation>[Instantiation.UNINSTANTIATED]);
+
   ClassElement _leastUpperInstantiatedSubclass;
 
   /// `true` if [cls] has been directly instantiated.
@@ -44,7 +106,22 @@
   ///   class C extends B {}
   ///   main() => new C();
   ///
-  bool isDirectlyInstantiated = false;
+  bool get isDirectlyInstantiated =>
+      _mask.contains(Instantiation.DIRECTLY_INSTANTIATED);
+
+  void set isDirectlyInstantiated(bool value) {
+    if (value != isDirectlyInstantiated) {
+      if (value) {
+        _mask.remove(Instantiation.UNINSTANTIATED);
+        _mask.add(Instantiation.DIRECTLY_INSTANTIATED);
+      } else {
+        _mask.remove(Instantiation.DIRECTLY_INSTANTIATED);
+        if (_mask.isEmpty) {
+          _mask.add(Instantiation.UNINSTANTIATED);
+        }
+      }
+    }
+  }
 
   /// `true` if [cls] has been instantiated through subclasses.
   ///
@@ -54,7 +131,22 @@
   ///   class C extends B {}
   ///   main() => [new B(), new C()];
   ///
-  bool isIndirectlyInstantiated = false;
+  bool get isIndirectlyInstantiated =>
+      _mask.contains(Instantiation.INDIRECTLY_INSTANTIATED);
+
+  void set isIndirectlyInstantiated(bool value) {
+    if (value != isIndirectlyInstantiated) {
+      if (value) {
+        _mask.remove(Instantiation.UNINSTANTIATED);
+        _mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
+      } else {
+        _mask.remove(Instantiation.INDIRECTLY_INSTANTIATED);
+        if (_mask.isEmpty) {
+          _mask.add(Instantiation.UNINSTANTIATED);
+        }
+      }
+    }
+  }
 
   /// The nodes for the direct subclasses of [cls].
   Link<ClassHierarchyNode> _directSubclasses = const Link<ClassHierarchyNode>();
@@ -94,12 +186,23 @@
        bool includeIndirectlyInstantiated: true,
        bool includeUninstantiated: true,
        bool strict: false}) {
-    return new ClassHierarchyNodeIterable(
-        this,
-        includeRoot: !strict,
+    EnumSet<Instantiation> mask = createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated: includeIndirectlyInstantiated,
+        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
         includeUninstantiated: includeUninstantiated);
+    return subclassesByMask(mask, strict: strict);
+  }
+
+  /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
+  ///
+  /// Subclasses are included if their instantiation properties intersect with
+  /// their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [cls] itself is _not_ returned.
+  Iterable<ClassElement> subclassesByMask(
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    return new ClassHierarchyNodeIterable(
+        this, mask, includeRoot: !strict);
   }
 
   /// Returns the most specific subclass of [cls] (including [cls]) that is
@@ -275,11 +378,22 @@
        bool includeIndirectlyInstantiated: true,
        bool includeUninstantiated: true,
        bool strict: false}) {
-    return node.subclasses(
-        strict: strict,
+    EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated: includeIndirectlyInstantiated,
+        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
         includeUninstantiated: includeUninstantiated);
+    return subclassesByMask(mask, strict: strict);
+  }
+
+  /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
+  ///
+  /// Subclasses are included if their instantiation properties intersect with
+  /// their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [cls] itself is _not_ returned.
+  Iterable<ClassElement> subclassesByMask(
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    return node.subclassesByMask(mask, strict: strict);
   }
 
   /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
@@ -293,18 +407,31 @@
        bool includeIndirectlyInstantiated: true,
        bool includeUninstantiated: true,
        bool strict: false}) {
-    if (_directSubtypes == null) {
-      return node.subclasses(
-          strict: strict,
-          includeDirectlyInstantiated: includeDirectlyInstantiated,
-          includeIndirectlyInstantiated: includeIndirectlyInstantiated,
-          includeUninstantiated: includeUninstantiated);
-    }
-    return new SubtypesIterable.SubtypesIterator(this,
-        includeRoot: !strict,
+    EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated: includeIndirectlyInstantiated,
+        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
         includeUninstantiated: includeUninstantiated);
+    return subtypesByMask(mask, strict: strict);
+  }
+
+
+  /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
+  ///
+  /// Subtypes are included if their instantiation properties intersect with
+  /// their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [cls] itself is _not_ returned.
+  Iterable<ClassElement> subtypesByMask(
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    if (_directSubtypes == null) {
+      return node.subclassesByMask(
+          mask,
+          strict: strict);
+    }
+
+    return new SubtypesIterable.SubtypesIterator(this,
+        mask,
+        includeRoot: !strict);
   }
 
   /// Adds [subtype] as a subtype of [cls].
@@ -412,17 +539,13 @@
 /// Iterable for subclasses of a [ClassHierarchyNode].
 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> {
   final ClassHierarchyNode root;
+  final EnumSet<Instantiation> mask;
   final bool includeRoot;
-  final bool includeDirectlyInstantiated;
-  final bool includeIndirectlyInstantiated;
-  final bool includeUninstantiated;
 
   ClassHierarchyNodeIterable(
       this.root,
-      {this.includeRoot: true,
-       this.includeDirectlyInstantiated: true,
-       this.includeIndirectlyInstantiated: true,
-       this.includeUninstantiated: true}) {
+      this.mask,
+      {this.includeRoot: true}) {
     if (root == null) throw new StateError("No root for iterable.");
   }
 
@@ -455,14 +578,12 @@
 
   bool get includeRoot => iterable.includeRoot;
 
-  bool get includeDirectlyInstantiated => iterable.includeDirectlyInstantiated;
+  EnumSet<Instantiation> get mask => iterable.mask;
 
-  bool get includeIndirectlyInstantiated {
-    return iterable.includeIndirectlyInstantiated;
+  bool get includeUninstantiated {
+    return mask.contains(Instantiation.UNINSTANTIATED);
   }
 
-  bool get includeUninstantiated => iterable.includeUninstantiated;
-
   @override
   ClassElement get current {
     return currentNode != null ? currentNode.cls : null;
@@ -511,33 +632,20 @@
   /// Returns `true` if the class of [node] is a valid result for this iterator.
   bool _isValid(ClassHierarchyNode node) {
     if (!includeRoot && node == root) return false;
-    if (includeDirectlyInstantiated && node.isDirectlyInstantiated) {
-      return true;
-    }
-    if (includeIndirectlyInstantiated && node.isIndirectlyInstantiated) {
-      return true;
-    }
-    if (includeUninstantiated && !node.isInstantiated) {
-      return true;
-    }
-    return false;
+    return mask.intersects(node._mask);
   }
 }
 
 /// Iterable for the subtypes in a [ClassSet].
 class SubtypesIterable extends IterableBase<ClassElement> {
   final ClassSet subtypeSet;
+  final EnumSet<Instantiation> mask;
   final bool includeRoot;
-  final bool includeDirectlyInstantiated;
-  final bool includeIndirectlyInstantiated;
-  final bool includeUninstantiated;
 
   SubtypesIterable.SubtypesIterator(
       this.subtypeSet,
-      {this.includeRoot: true,
-       this.includeDirectlyInstantiated: true,
-       this.includeIndirectlyInstantiated: true,
-       this.includeUninstantiated: true});
+      this.mask,
+      {this.includeRoot: true});
 
   @override
   Iterator<ClassElement> get iterator => new SubtypesIterator(this);
@@ -553,13 +661,7 @@
 
   bool get includeRoot => iterable.includeRoot;
 
-  bool get includeDirectlyInstantiated => iterable.includeDirectlyInstantiated;
-
-  bool get includeIndirectlyInstantiated {
-    return iterable.includeIndirectlyInstantiated;
-  }
-
-  bool get includeUninstantiated => iterable.includeUninstantiated;
+  EnumSet<Instantiation> get mask => iterable.mask;
 
   @override
   ClassElement get current {
@@ -573,11 +675,9 @@
   bool moveNext() {
     if (elements == null && hierarchyNodes == null) {
       // Initial state. Iterate through subclasses.
-      elements = iterable.subtypeSet.node.subclasses(
-          strict: !includeRoot,
-          includeDirectlyInstantiated: includeDirectlyInstantiated,
-          includeIndirectlyInstantiated: includeIndirectlyInstantiated,
-          includeUninstantiated: includeUninstantiated).iterator;
+      elements = iterable.subtypeSet.node.subclassesByMask(
+          mask,
+          strict: !includeRoot).iterator;
     }
     if (elements != null && elements.moveNext()) {
       return true;
@@ -587,10 +687,7 @@
       hierarchyNodes = iterable.subtypeSet._directSubtypes.iterator;
     }
     while (hierarchyNodes.moveNext()) {
-      elements = hierarchyNodes.current.subclasses(
-          includeDirectlyInstantiated: includeDirectlyInstantiated,
-          includeIndirectlyInstantiated: includeIndirectlyInstantiated,
-          includeUninstantiated: includeUninstantiated).iterator;
+      elements = hierarchyNodes.current.subclassesByMask(mask).iterator;
       if (elements.moveNext()) {
         return true;
       }
diff --git a/pkg/compiler/lib/src/util/enumset.dart b/pkg/compiler/lib/src/util/enumset.dart
new file mode 100644
index 0000000..953a873
--- /dev/null
+++ b/pkg/compiler/lib/src/util/enumset.dart
@@ -0,0 +1,199 @@
+// Copyright (c) 2016, 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 dart2js.util.enumset;
+
+import 'dart:collection';
+
+/// A set of enum values based on a bit mask of the shifted enum indices.
+abstract class EnumSet<E> {
+  /// Creates an empty mutable set.
+  factory EnumSet() = _EnumSet<E>;
+
+  /// Creates a mutable set from the bit mask [value].
+  factory EnumSet.fromValue(int value) = _EnumSet<E>.fromValue;
+
+  /// Creates an immutable set from the bit mask [value].
+  const factory EnumSet.fixed(int value) = _ConstEnumSet<E>;
+
+  /// Create a set containing the [values]. If [fixed] is `true` the set is
+  /// immutable.
+  factory EnumSet.fromValues(Iterable<E> values, {bool fixed: false}) {
+    if (fixed) {
+      return new _ConstEnumSet<E>.fromValues(values);
+    } else {
+      return new _EnumSet<E>.fromValues(values);
+    }
+  }
+
+  const EnumSet._();
+
+  /// The bit mask of the shifted indices for the enum values in this set.
+  int get value;
+
+  /// Adds [enumValue] to this set.
+  void add(E enumValue);
+
+  /// Removes [enumValue] from this set.
+  void remove(E enumValue);
+
+  /// Clears this set.
+  void clear();
+
+  /// Returns `true` if [enumValue] is in this set.
+  bool contains(E enumValue) {
+    return (value & (1 << (enumValue as dynamic).index)) != 0;
+  }
+
+  /// Returns an [Iterable] of the values is in this set using [values] to
+  /// convert the stored indices to enum values.
+  ///
+  /// The method is typically called with the `values` property of the enum
+  /// class as argument:
+  ///
+  ///     EnumSet<EnumClass> set = ...
+  ///     Iterable<EnumClass> iterable = set.iterable(EnumClass.values);
+  ///
+  Iterable<E> iterable(List<E> values) {
+    return new _EnumSetIterable(this, values);
+  }
+
+  /// Returns `true` if this and [other] have any elements in common.
+  bool intersects(EnumSet<E> other) {
+    return (value & other.value) != 0;
+  }
+
+  /// Returns `true` if this set is empty.
+  bool get isEmpty => value == 0;
+
+  int get hashCode => value.hashCode * 19;
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! EnumSet<E>) return false;
+    return value == other.value;
+  }
+
+  String toString() {
+    if (value == 0) return '0';
+    int index = value.bitLength - 1;
+    StringBuffer sb = new StringBuffer();
+    int mask = 1 << index;
+    while (index >= 0) {
+      sb.write((value & mask) != 0 ? '1' : '0');
+      index--;
+      mask >>= 1;
+    }
+    return sb.toString();
+  }
+}
+
+/// Mutable implementation of [EnumSet].
+class _EnumSet<E> extends EnumSet<E> {
+  int _value;
+
+  _EnumSet() : this.fromValue(0);
+
+  _EnumSet.fromValue(this._value) : super._();
+
+  _EnumSet.fromValues(Iterable<E> values)
+      : this._value = 0,
+        super._() {
+    values.forEach(add);
+  }
+
+  int get value => _value;
+
+  void add(E enumValue) {
+    _value |= 1 << (enumValue as dynamic).index;
+  }
+
+  void remove(E enumValue) {
+    _value &= ~(1 << (enumValue as dynamic).index);
+  }
+
+  void clear() {
+    _value = 0;
+  }
+}
+
+/// Immutable implementation of [EnumSet].
+class _ConstEnumSet<E> extends EnumSet<E> {
+  final int value;
+
+  const _ConstEnumSet(this.value) : super._();
+
+  factory _ConstEnumSet.fromValues(Iterable<E> values) {
+    int value = 0;
+    void add(E enumValue) {
+      if (enumValue != null) {
+        value |= 1 << (enumValue as dynamic).index;
+      }
+    }
+    values.forEach(add);
+    return new _ConstEnumSet(value);
+  }
+
+  @override
+  void add(E enumValue) {
+    throw new UnsupportedError('EnumSet.add');
+  }
+
+  @override
+  void clear() {
+    throw new UnsupportedError('EnumSet.clear');
+  }
+
+  @override
+  void remove(E enumValue) {
+    throw new UnsupportedError('EnumSet.remove');
+  }
+}
+
+class _EnumSetIterable<E> extends IterableBase<E> {
+  final EnumSet<E> _enumSet;
+  final List<E> _values;
+
+  _EnumSetIterable(this._enumSet, this._values);
+
+  @override
+  Iterator<E> get iterator => new _EnumSetIterator(_enumSet.value, _values);
+}
+
+class _EnumSetIterator<E> implements Iterator<E> {
+  int _value;
+  int _index;
+  int _mask;
+  final List<E> _values;
+  E _current;
+
+  _EnumSetIterator(this._value, this._values);
+
+  @override
+  E get current => _current;
+
+  @override
+  bool moveNext() {
+    if (_value == 0) {
+      return false;
+    } else {
+      if (_mask == null) {
+        _index = _value.bitLength - 1;
+        _mask = 1 << _index;
+      }
+      _current = null;
+      while (_index >= 0) {
+        if (_mask & _value != 0) {
+          _current = _values[_index];
+        }
+        _mask >>= 1;
+        _index--;
+        if (_current != null) {
+          break;
+        }
+      }
+      return _current != null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 22adbfa..30b2081 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -235,9 +235,8 @@
   Iterable<ClassElement> subclassesOf(ClassElement cls) {
     ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
     if (hierarchy == null) return const <ClassElement>[];
-    return hierarchy.subclasses(
-        includeIndirectlyInstantiated: false,
-        includeUninstantiated: false);
+    return hierarchy.subclassesByMask(
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED);
   }
 
   /// Returns an iterable over the directly instantiated classes that extend
@@ -245,10 +244,8 @@
   Iterable<ClassElement> strictSubclassesOf(ClassElement cls) {
     ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
     if (subclasses == null) return const <ClassElement>[];
-    return subclasses.subclasses(
-        strict: true,
-        includeIndirectlyInstantiated: false,
-        includeUninstantiated: false);
+    return subclasses.subclassesByMask(
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
   }
 
   /// Returns an iterable over the directly instantiated that implement [cls]
@@ -258,9 +255,7 @@
     if (classSet == null) {
       return const <ClassElement>[];
     } else {
-      return classSet.subtypes(
-          includeIndirectlyInstantiated: false,
-          includeUninstantiated: false);
+      return classSet.subtypesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED);
     }
   }
 
@@ -271,10 +266,9 @@
     if (classSet == null) {
       return const <ClassElement>[];
     } else {
-      return classSet.subtypes(
-          strict: true,
-          includeIndirectlyInstantiated: false,
-          includeUninstantiated: false);
+      return classSet.subtypesByMask(
+          ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+          strict: true);
     }
   }
 
diff --git a/pkg/pkg.status b/pkg/pkg.status
index c821f54..8f29f55 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -43,12 +43,13 @@
 analysis_server/test/search/top_level_declarations_test: Pass, Slow # 19756, 21628
 analysis_server/test/services/index/store/codec_test: Pass, Slow
 analysis_server/test/socket_server_test: Pass, Slow # Issue 19756, 21628
+analyzer/test/dart/element/element_test: Pass, Slow # Issue 24914
 analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
 analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
 analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
 analyzer/test/generated/compile_time_error_code_test: Pass, Slow
 analyzer/test/generated/compile_time_error_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/declaration_resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/declaration_resolver_test: Pass, Slow # Issue 24914
 analyzer/test/generated/element_test: Pass, Slow # Issue 21628
 analyzer/test/generated/engine_test: SkipSlow
 analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
@@ -64,9 +65,10 @@
 analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
 analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
 analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
-analyzer/test/src/dart/element/element_test: Pass, Slow # Issue 21628
+analyzer/test/src/dart/element/element_test: Pass, Slow # Issue 24914
 analyzer/test/src/summary/resynthesize_test: Pass, Slow
-analyzer/test/src/summary/summary_test: Pass, Slow # Issue 21628
+analyzer/test/src/summary/summary_sdk_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/summary_test: Pass, Slow # Issue 24914
 analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/driver_test: Pass, Slow # Issue 21628
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index 2404f3e..1366f47 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -2,22 +2,15 @@
 # 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.
 
-samples/third_party/dromaeo: Pass, Slow
 samples/searchable_list: Pass, Slow
 
 [ $use_repository_packages ]
 pkg/analyzer: PubGetError
 samples/third_party/angular_todo: Fail # angular needs to be updated
-samples/third_party/todomvc_performance: Skip # dependencies are not in the repo
 
 [ $use_public_packages ]
 pkg/compiler: SkipByDesign # js_ast is not published
 samples/third_party/angular_todo: Pass, Slow
-samples/third_party/todomvc_performance: Pass, Slow
 
 [ $builder_tag == russian ]
 samples/third_party/angular_todo: Fail # Issue 16356
-samples/third_party/dromaeo: Fail # Issue 23760
-
-[ $use_public_packages && $system == windows ]
-samples/third_party/todomvc_performance: Fail # Issue 18086
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index dc374f6..f162bcb 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -89,12 +89,19 @@
 
 // Packages are either resolved looking up in a map or resolved from within a
 // package root.
-bool _packagesReady() => (_packageRoot != null) || (_packageMap != null);
+bool get _packagesReady =>
+    (_packageRoot != null) || (_packageMap != null) || (_packageError != null);
+// Error string set if there was an error resolving package configuration.
+// For example not finding a .packages file or packages/ directory, malformed
+// .packages file or any other related error.
+String _packageError = null;
 // The directory to look in to resolve "package:" scheme URIs. By detault it is
 // the 'packages' directory right next to the script.
 Uri _packageRoot = null; // Used to be _rootScript.resolve('packages/');
 // The map describing how certain package names are mapped to Uris.
+Uri _packageConfig = null;
 Map<String, Uri> _packageMap = null;
+
 // A list of pending packags which have been requested while resolving the
 // location of the package root or the contents of the package map.
 List<_LoadRequest> _pendingPackageLoads = [];
@@ -109,8 +116,9 @@
 bool _isWindows = false;
 
 // Logging from builtin.dart is prefixed with a '*'.
+String _logId = (Isolate.current.hashCode % 0x100000).toRadixString(16);
 _log(msg) {
-  _print("* $msg");
+  _print("* $_logId $msg");
 }
 
 // A class wrapping the load error message in an Error object.
@@ -235,8 +243,10 @@
     _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
   }
   // Now that we have determined the packageRoot value being used, set it
-  // up for use in Platform.packageRoot.
-  VMLibraryHooks.packageRoot = _packageRoot.toString();
+  // up for use in Platform.packageRoot. This is only set when the embedder
+  // sets up the package root. Automatically discovered package root will
+  // not update the VMLibraryHooks value.
+  VMLibraryHooks.packageRootString = _packageRoot.toString();
   if (_traceLoading) {
     _log('Package root URI: $_packageRoot');
   }
@@ -246,6 +256,9 @@
 // Given a uri with a 'package' scheme, return a Uri that is prefixed with
 // the package root.
 Uri _resolvePackageUri(Uri uri) {
+  assert(uri.scheme == "package");
+  assert(_packagesReady);
+
   if (!uri.host.isEmpty) {
     var path = '${uri.host}${uri.path}';
     var right = 'package:$path';
@@ -259,7 +272,12 @@
     _log('Resolving package with uri path: ${uri.path}');
   }
   var resolvedUri;
-  if (_packageRoot != null) {
+  if (_packageError != null) {
+    if (_traceLoading) {
+      _log("Resolving package with pending resolution error: $_packageError");
+    }
+    throw _packageError;
+  } else if (_packageRoot != null) {
     resolvedUri = _packageRoot.resolve(uri.path);
   } else {
     var packageName = uri.pathSegments[0];
@@ -408,22 +426,33 @@
     if (_traceLoading) {
       _log("Got failure response on package port: '$msg'");
     }
-    throw msg;
-  }
-  if (msg.length == 1) {
-    if (_traceLoading) {
-      _log("Received package root: '${msg[0]}'");
+    // Remember the error message.
+    _packageError = msg;
+  } else if (msg is List) {
+    if (msg.length == 1) {
+      if (_traceLoading) {
+        _log("Received package root: '${msg[0]}'");
+      }
+      _packageRoot = Uri.parse(msg[0]);
+    } else {
+      // First entry contains the location of the loaded .packages file.
+      assert((msg.length % 2) == 0);
+      assert(msg.length >= 2);
+      assert(msg[1] == null);
+      _packageConfig = Uri.parse(msg[0]);
+      _packageMap = new Map<String, Uri>();
+      for (var i = 2; i < msg.length; i+=2) {
+        // TODO(iposva): Complain about duplicate entries.
+        _packageMap[msg[i]] = Uri.parse(msg[i+1]);
+      }
+      if (_traceLoading) {
+        _log("Setup package map: $_packageMap");
+      }
     }
-    _packageRoot = Uri.parse(msg[0]);
   } else {
-    assert((msg.length % 2) == 0);
-    _packageMap = new Map<String, Uri>();
-    for (var i = 0; i < msg.length; i+=2) {
-      // TODO(iposva): Complain about duplicate entries.
-      _packageMap[msg[i]] = Uri.parse(msg[i+1]);
-    }
+    _packageError = "Bad type of packages reply: ${msg.runtimeType}";
     if (_traceLoading) {
-      _log("Setup package map: $_packageMap");
+      _log(_packageError);
     }
   }
 
@@ -485,7 +514,8 @@
     // resolve it against the working directory.
     packagesUri = _workingDirectory.resolveUri(packagesUri);
   }
-  VMLibraryHooks.packageConfig = packagesUri.toString();
+  var packagesUriStr = packagesUri.toString();
+  VMLibraryHooks.packageConfigString = packagesUriStr;
   if (_traceLoading) {
     _log('Resolved packages map to: $packagesUri');
   }
@@ -500,7 +530,7 @@
   msg[0] = sp;
   msg[1] = _traceLoading;
   msg[2] = -2;
-  msg[3] = packagesUri.toString();
+  msg[3] = packagesUriStr;
   _loadPort.send(msg);
 
   // Signal that the resolution of the packages map has started. But in this
@@ -519,34 +549,6 @@
 }
 
 
-// Embedder Entrypoint:
-// Add mapping from package name to URI.
-void _addPackageMapEntry(String key, String value) {
-  if (!_setupCompleted) {
-    _setupHooks();
-  }
-  if (_traceLoading) {
-    _log("Adding packages map entry: $key -> $value");
-  }
-  if (_packageRoot != null) {
-    if (_traceLoading) {
-      _log("_packageRoot already set: $_packageRoot");
-    }
-    throw "Cannot add package map entry to an exisiting package root.";
-  }
-  if (_packagesPort != null) {
-    if (_traceLoading) {
-      _log("Package map load request already pending.");
-    }
-    throw "Cannot add package map entry during package map resolution.";
-  }
-  if (_packageMap == null) {
-    _packageMap = new Map<String, Uri>();
-  }
-  _packageMap[key] = _workingDirectory.resolve(value);
-}
-
-
 void _asyncLoadError(_LoadRequest req, _LoadError error, StackTrace stack) {
   if (_traceLoading) {
     _log("_asyncLoadError(${req._uri}), error: $error\nstack: $stack");
@@ -587,8 +589,22 @@
 // Loading a package URI needs to first map the package name to a loadable
 // URI.
 _loadPackage(int tag, String uri, Uri resourceUri, context) {
-  if (_packagesReady()) {
-    _loadData(tag, uri, _resolvePackageUri(resourceUri), context);
+  if (_packagesReady) {
+    var resolvedUri;
+    try {
+      resolvedUri = _resolvePackageUri(resourceUri);
+    } catch (e, s) {
+      if (_traceLoading) {
+        _log("Exception ($e) when resolving package URI: $resourceUri");
+      }
+      // Wrap inside a _LoadError unless we are already propagating a previously
+      // seen _LoadError.
+      var error = (e is _LoadError) ? e : new _LoadError(uri, e.toString());
+      // Register a dummy load request and fail to load it.
+      var req = new _LoadRequest(tag, uri, resourceUri, context);
+      _asyncLoadError(req, error, s);
+    }
+    _loadData(tag, uri, resolvedUri, context);
   } else {
     if (_pendingPackageLoads.isEmpty) {
       // Package resolution has not been setup yet, and this is the first
@@ -606,7 +622,7 @@
     });
     if (_traceLoading) {
       _log("Pending package load of '$uri': "
-      "${_pendingPackageLoads.length} pending");
+           "${_pendingPackageLoads.length} pending");
     }
   }
 }
@@ -669,7 +685,7 @@
 
 // Handling of access to the package root or package map from user code.
 _triggerPackageResolution(action) {
-  if (_packagesReady()) {
+  if (_packagesReady) {
     // Packages are ready. Execute the action now.
     action();
   } else {
@@ -684,7 +700,7 @@
 }
 
 
-Future<Uri> _getPackageRoot() {
+Future<Uri> _getPackageRootFuture() {
   if (_traceLoading) {
     _log("Request for package root from user code.");
   }
@@ -696,19 +712,47 @@
 }
 
 
-Future<Map<String, Uri>> _getPackageMap() {
+Future<Uri> _getPackageConfigFuture() {
   if (_traceLoading) {
-    _log("Request for package map from user code.");
+    _log("Request for package config from user code.");
   }
-  var completer = new Completer<Map<String, Uri>>();
+  var completer = new Completer<Uri>();
   _triggerPackageResolution(() {
-    var result = (_packageMap != null) ? new Map.from(_packageMap) : {};
-    completer.complete(result);
+    completer.complete(_packageConfig);
   });
   return completer.future;
 }
 
 
+Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
+  if (_traceLoading) {
+    _log("Request for package Uri resolution from user code: $packageUri");
+  }
+  if (packageUri.scheme != "package") {
+    if (_traceLoading) {
+      _log("Non-package Uri, returning unmodified: $packageUri");
+    }
+    // Return the incoming parameter if not passed a package: URI.
+    return packageUri;
+  }
+
+  if (!_packagesReady) {
+    if (_traceLoading) {
+      _log("Trigger loading by requesting the package config.");
+    }
+    // Make sure to trigger package resolution.
+    var dummy = await _getPackageConfigFuture();
+  }
+  assert(_packagesReady);
+
+  var result = _resolvePackageUri(packageUri);
+  if (_traceLoading) {
+    _log("Resolved '$packageUri' to '$result'");
+  }
+  return result;
+}
+
+
 // Handling of Resource class by dispatching to the load port.
 Future<List<int>> _resourceReadAsBytes(Uri uri) {
   var completer = new Completer<List<int>>();
@@ -836,6 +880,8 @@
 _setupHooks() {
   _setupCompleted = true;
   VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes;
-  VMLibraryHooks.getPackageRoot = _getPackageRoot;
-  VMLibraryHooks.getPackageMap = _getPackageMap;
+
+  VMLibraryHooks.packageRootUriFuture = _getPackageRootFuture;
+  VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture;
+  VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
 }
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index e86fad9..8915011 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -658,8 +658,7 @@
                                              bool is_service_isolate,
                                              bool trace_loading,
                                              const char* package_root,
-                                             const char** package_map,
-                                             const char* packages_file) {
+                                             const char* packages_config) {
   // Setup the internal library's 'internalPrint' function.
   Dart_Handle print = Dart_Invoke(
       builtin_lib, NewString("_getPrintClosure"), 0, NULL);
@@ -693,8 +692,7 @@
 
   // Set up package root if specified.
   if (package_root != NULL) {
-    ASSERT(package_map == NULL);
-    ASSERT(packages_file == NULL);
+    ASSERT(packages_config == NULL);
     result = NewString(package_root);
     RETURN_IF_ERROR(result);
     const int kNumArgs = 1;
@@ -705,35 +703,8 @@
                          kNumArgs,
                          dart_args);
     RETURN_IF_ERROR(result);
-  } else if (package_map != NULL) {
-    ASSERT(packages_file == NULL);
-    Dart_Handle func_name = NewString("_addPackageMapEntry");
-    RETURN_IF_ERROR(func_name);
-
-    for (int i = 0; package_map[i] != NULL; i +=2) {
-      const int kNumArgs = 2;
-      Dart_Handle dart_args[kNumArgs];
-      // Get the key.
-      result = NewString(package_map[i]);
-      RETURN_IF_ERROR(result);
-      dart_args[0] = result;
-      if (package_map[i + 1] == NULL) {
-        return Dart_NewUnhandledExceptionError(
-            NewDartArgumentError("Adding package map entry without value."));
-      }
-      // Get the value.
-      result = NewString(package_map[i + 1]);
-      RETURN_IF_ERROR(result);
-      dart_args[1] = result;
-      // Setup the next package map entry.
-      result = Dart_Invoke(builtin_lib,
-                           func_name,
-                           kNumArgs,
-                           dart_args);
-      RETURN_IF_ERROR(result);
-    }
-  } else if (packages_file != NULL) {
-    result = NewString(packages_file);
+  } else if (packages_config != NULL) {
+    result = NewString(packages_config);
     RETURN_IF_ERROR(result);
     const int kNumArgs = 1;
     Dart_Handle dart_args[kNumArgs];
@@ -789,8 +760,7 @@
 
 
 Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
-                                               const char** package_map,
-                                               const char* packages_file,
+                                               const char* packages_config,
                                                bool is_service_isolate,
                                                bool trace_loading,
                                                Dart_Handle builtin_lib) {
@@ -824,8 +794,7 @@
                                  is_service_isolate,
                                  trace_loading,
                                  package_root,
-                                 package_map,
-                                 packages_file);
+                                 packages_config);
   RETURN_IF_ERROR(result);
 
   RETURN_IF_ERROR(PrepareAsyncLibrary(async_lib, isolate_lib));
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 2c497b2..68ad7ed 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -130,7 +130,6 @@
                                            bool is_service_isolate,
                                            bool trace_loading,
                                            const char* package_root,
-                                           const char** package_map,
                                            const char* packages_file);
   static Dart_Handle PrepareCoreLibrary(Dart_Handle core_lib,
                                  Dart_Handle builtin_lib,
@@ -140,7 +139,6 @@
   static Dart_Handle PrepareIOLibrary(Dart_Handle io_lib);
   static Dart_Handle PrepareIsolateLibrary(Dart_Handle isolate_lib);
   static Dart_Handle PrepareForScriptLoading(const char* package_root,
-                                             const char** package_map,
                                              const char* packages_file,
                                              bool is_service_isolate,
                                              bool trace_loading,
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 93611a4..0e12574 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -955,7 +955,7 @@
 static Dart_Isolate CreateServiceIsolate(const char* script_uri,
                                          const char* main,
                                          const char* package_root,
-                                         const char** package_map,
+                                         const char* package_config,
                                          Dart_IsolateFlags* flags,
                                          void* data,
                                          char** error) {
@@ -1095,7 +1095,6 @@
     result =
         DartUtils::PrepareForScriptLoading(package_root,
                                            NULL,
-                                           NULL,
                                            false,
                                            false,
                                            builtin_lib);
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index 611b458..03d20d4 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -9,6 +9,7 @@
     'eventhandler.cc',
     'eventhandler.h',
     'eventhandler_android.cc',
+    'eventhandler_android.h',
     'eventhandler_linux.cc',
     'eventhandler_linux.h',
     'eventhandler_macos.cc',
@@ -48,9 +49,13 @@
     'socket.cc',
     'socket.h',
     'socket_android.cc',
+    'socket_android.h',
     'socket_linux.cc',
+    'socket_linux.h',
     'socket_macos.cc',
+    'socket_macos.h',
     'socket_win.cc',
+    'socket_win.h',
     'stdio.cc',
     'stdio.h',
     'stdio_android.cc',
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 71a6b65..5e57327 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -604,7 +604,24 @@
   if ((commandline_package_root != NULL) &&
       (commandline_packages_file != NULL)) {
     Log::PrintErr("Specifying both a packages directory and a packages "
-                  "file is invalid.");
+                  "file is invalid.\n");
+    return -1;
+  }
+  if (has_noopt) {
+    if (has_gen_precompiled_snapshot) {
+      Log::PrintErr("Specifying --noopt and --gen_precompiled_snapshot"
+                    " is invalid.\n");
+      return -1;
+    }
+    if (has_run_precompiled_snapshot) {
+      Log::PrintErr("Specifying --noopt and --run_precompiled_snapshot"
+                    " is invalid.\n");
+      return -1;
+    }
+  }
+  if (has_gen_precompiled_snapshot && has_run_precompiled_snapshot) {
+    Log::PrintErr("Specifying --gen_precompiled_snapshot and"
+                  " --run_precompiled_snapshot is invalid.\n");
     return -1;
   }
 
@@ -687,15 +704,14 @@
 static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
                                                 const char* main,
                                                 const char* package_root,
-                                                const char** package_map,
-                                                const char* packages_file,
+                                                const char* packages_config,
                                                 Dart_IsolateFlags* flags,
                                                 char** error,
                                                 int* exit_code) {
   ASSERT(script_uri != NULL);
   IsolateData* isolate_data = new IsolateData(script_uri,
                                               package_root,
-                                              packages_file);
+                                              packages_config);
   Dart_Isolate isolate = NULL;
 
   isolate = Dart_CreateIsolate(script_uri,
@@ -751,8 +767,7 @@
   // Prepare for script loading by setting up the 'print' and 'timer'
   // closures and setting up 'package root' for URI resolution.
   result = DartUtils::PrepareForScriptLoading(package_root,
-                                              package_map,
-                                              packages_file,
+                                              packages_config,
                                               false,
                                               has_trace_loading,
                                               builtin_lib);
@@ -798,45 +813,23 @@
 static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
                                           const char* main,
                                           const char* package_root,
-                                          const char** package_map,
+                                          const char* package_config,
                                           Dart_IsolateFlags* flags,
                                           void* data, char** error) {
   // The VM should never call the isolate helper with a NULL flags.
   ASSERT(flags != NULL);
   ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
-  if ((package_root != NULL) && (package_map != NULL)) {
+  if ((package_root != NULL) && (package_config != NULL)) {
     *error = strdup("Invalid arguments - Cannot simultaneously specify "
                     "package root and package map.");
     return NULL;
   }
-  IsolateData* parent_isolate_data = reinterpret_cast<IsolateData*>(data);
-  if (script_uri == NULL) {
-    if (data == NULL) {
-      *error = strdup("Invalid 'callback_data' - Unable to spawn new isolate");
-      return NULL;
-    }
-    script_uri = parent_isolate_data->script_url;
-    if (script_uri == NULL) {
-      *error = strdup("Invalid 'callback_data' - Unable to spawn new isolate");
-      return NULL;
-    }
-  }
-  const char* packages_file = NULL;
-  // If neither a package root nor a package map are requested pass on the
-  // inherited values.
-  if ((package_root == NULL) && (package_map == NULL)) {
-    if (parent_isolate_data != NULL) {
-      package_root = parent_isolate_data->package_root;
-      packages_file = parent_isolate_data->packages_file;
-    }
-  }
 
   int exit_code = 0;
   return CreateIsolateAndSetupHelper(script_uri,
                                      main,
                                      package_root,
-                                     package_map,
-                                     packages_file,
+                                     package_config,
                                      flags,
                                      error,
                                      &exit_code);
@@ -1149,7 +1142,6 @@
   Dart_Isolate isolate = CreateIsolateAndSetupHelper(script_name,
                                                      "main",
                                                      commandline_package_root,
-                                                     NULL,
                                                      commandline_packages_file,
                                                      NULL,
                                                      &error,
@@ -1207,6 +1199,11 @@
       }
     }
 
+    if (has_compile_all) {
+      result = Dart_CompileAll();
+      CHECK_RESULT(result);
+    }
+
     if (has_noopt || has_gen_precompiled_snapshot) {
       Dart_QualifiedFunctionName standalone_entry_points[] = {
         { "dart:_builtin", "::", "_getMainClosure" },
@@ -1215,7 +1212,6 @@
         { "dart:_builtin", "::", "_resolveUri" },
         { "dart:_builtin", "::", "_setWorkingDirectory" },
         { "dart:_builtin", "::", "_setPackageRoot" },
-        { "dart:_builtin", "::", "_addPackageMapEntry" },
         { "dart:_builtin", "::", "_loadPackagesMap" },
         { "dart:_builtin", "::", "_loadDataAsync" },
         { "dart:io", "::", "_makeUint8ListView" },
@@ -1223,7 +1219,11 @@
         { "dart:io", "::", "_setupHooks" },
         { "dart:io", "::", "_getWatchSignalInternal" },
         { "dart:io", "CertificateException", "CertificateException." },
+        { "dart:io", "Directory", "Directory." },
+        { "dart:io", "File", "File." },
+        { "dart:io", "FileSystemException", "FileSystemException." },
         { "dart:io", "HandshakeException", "HandshakeException." },
+        { "dart:io", "Link", "Link." },
         { "dart:io", "OSError", "OSError." },
         { "dart:io", "TlsException", "TlsException." },
         { "dart:io", "X509Certificate", "X509Certificate._" },
@@ -1267,11 +1267,6 @@
                                    instructions_buffer,
                                    instructions_size);
     } else {
-      if (has_compile_all) {
-        result = Dart_CompileAll();
-        CHECK_RESULT(result);
-      }
-
       if (Dart_IsNull(root_lib)) {
         ErrorExit(kErrorExitCode,
                   "Unable to find root library for '%s'\n",
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index dec7493..50439c5 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -5,17 +5,25 @@
 patch class _Platform {
   /* patch */ static int _numberOfProcessors()
       native "Platform_NumberOfProcessors";
-  /* patch */ static String _pathSeparator() native "Platform_PathSeparator";
+  /* patch */ static String _pathSeparator()
+      native "Platform_PathSeparator";
   /* patch */ static String _operatingSystem()
       native "Platform_OperatingSystem";
-  /* patch */ static _localHostname() native "Platform_LocalHostname";
-  /* patch */ static _executable() native "Platform_ExecutableName";
+  /* patch */ static _localHostname()
+      native "Platform_LocalHostname";
+  /* patch */ static _executable()
+      native "Platform_ExecutableName";
   /* patch */ static _resolvedExecutable()
       native "Platform_ResolvedExecutableName";
-  /* patch */ static _environment() native "Platform_Environment";
+  /* patch */ static _environment()
+      native "Platform_Environment";
   /* patch */ static List<String> _executableArguments()
-       native "Platform_ExecutableArguments";
-  /* patch */ static String _packageRoot() => VMLibraryHooks.packageRoot;
-  /* patch */ static String _packageConfig() => VMLibraryHooks.packageConfig;
-  /* patch */ static String _version() native "Platform_GetVersion";
+      native "Platform_ExecutableArguments";
+  /* patch */ static String _version()
+      native "Platform_GetVersion";
+
+  /* patch */ static String _packageRoot()
+      => VMLibraryHooks.packageRootString;
+  /* patch */ static String _packageConfig()
+      => VMLibraryHooks.packageConfigString;
 }
diff --git a/runtime/bin/utils_macos.cc b/runtime/bin/utils_macos.cc
index 5ac414f..eea4cb7 100644
--- a/runtime/bin/utils_macos.cc
+++ b/runtime/bin/utils_macos.cc
@@ -13,6 +13,10 @@
 #include <sys/time.h>  // NOLINT
 #include <time.h>  // NOLINT
 
+#if TARGET_OS_IOS
+#include <sys/sysctl.h>  // NOLINT
+#endif
+
 #include "bin/utils.h"
 #include "platform/assert.h"
 #include "platform/utils.h"
@@ -85,6 +89,20 @@
   return GetCurrentMonotonicMicros() / 1000;
 }
 
+#if TARGET_OS_IOS
+
+static int64_t GetCurrentTimeMicros() {
+  // gettimeofday has microsecond resolution.
+  struct timeval tv;
+  if (gettimeofday(&tv, NULL) < 0) {
+    UNREACHABLE();
+    return 0;
+  }
+  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
+}
+
+#endif  // TARGET_OS_IOS
+
 int64_t TimerUtils::GetCurrentMonotonicMicros() {
 #if TARGET_OS_IOS
   // On iOS mach_absolute_time stops while the device is sleeping. Instead use
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 38b62b1..6bc8c45 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -132,7 +132,9 @@
                    bool traceLoading,
                    Uri packagesFile,
                    List<int> data) {
-  var result = [];
+  // The first entry contains the location of the identified .packages file
+  // instead of a mapping.
+  var result = [packagesFile.toString(), null];
   var index = 0;
   var len = data.length;
   while (index < len) {
diff --git a/runtime/bin/vmservice_dartium.cc b/runtime/bin/vmservice_dartium.cc
index 0ff30a7..cd2c87f 100644
--- a/runtime/bin/vmservice_dartium.cc
+++ b/runtime/bin/vmservice_dartium.cc
@@ -68,7 +68,7 @@
   // Prepare for script loading by setting up the 'print' and 'timer'
   // closures and setting up 'package root' for URI resolution.
   result = DartUtils::PrepareForScriptLoading(
-      NULL, NULL, NULL, true, false, builtin_lib);
+      NULL, NULL, true, false, builtin_lib);
   CHECK_RESULT(result);
 
   ASSERT(Dart_IsServiceIsolate(isolate));
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 2715abc..0c0a63c 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -183,7 +183,7 @@
   // Prepare for script loading by setting up the 'print' and 'timer'
   // closures and setting up 'package root' for URI resolution.
   result = DartUtils::PrepareForScriptLoading(
-      NULL, NULL, NULL, true, false, builtin_lib);
+      NULL, NULL, true, false, builtin_lib);
   SHUTDOWN_ON_ERROR(result);
 
   if (running_precompiled) {
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index fd3701e..707686f 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -81,6 +81,7 @@
       'defines': [
         # The only effect of DART_SHARED_LIB is to export the Dart API entries.
         'DART_SHARED_LIB',
+        'DART_PRECOMPILED',
       ],
       'direct_dependent_settings': {
         'include_dirs': [
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 222ef79..4249382 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -583,6 +583,8 @@
   int32_t version;
   bool enable_type_checks;
   bool enable_asserts;
+  bool enable_error_on_bad_type;
+  bool enable_error_on_bad_override;
 } Dart_IsolateFlags;
 
 /**
@@ -643,7 +645,7 @@
 typedef Dart_Isolate (*Dart_IsolateCreateCallback)(const char* script_uri,
                                                    const char* main,
                                                    const char* package_root,
-                                                   const char** package_map,
+                                                   const char* package_config,
                                                    Dart_IsolateFlags* flags,
                                                    void* callback_data,
                                                    char** error);
@@ -908,19 +910,6 @@
  * "pure" dart isolate. Implement and document. */
 
 /**
- * Enables/Disables strict compilation for the current Isolate.
- * Strict compilation includes:
- * - type-checking
- * - asserts
- * - errors on bad types
- * - errors on bad overrides
- *
- * This call requires there to be a current isolate, and requires that there has
- * not yet been any compilation for the current Isolate.
- */
-DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value);
-
-/**
  * Creates a full snapshot of the current isolate heap.
  *
  * A full snapshot is a compact representation of the dart vm isolate heap
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 2227603..bba7c38 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -23,10 +23,11 @@
   static var resourceReadAsBytes;
 
   // Implementation of package root/map provision.
-  static var packageRoot;
-  static var packageConfig;
-  static var getPackageRoot;
-  static var getPackageMap;
+  static var packageRootString;
+  static var packageConfigString;
+  static var packageRootUriFuture;
+  static var packageConfigUriFuture;
+  static var resolvePackageUriFuture;
 }
 
 patch class CodeUnits {
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 21f1274..dd93fbe 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -143,6 +143,7 @@
     char* error = NULL;
     Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
     if (callback == NULL) {
+      state_->DecrementSpawnCount();
       ReportError(
           "Isolate spawn is not supported by this Dart implementation\n");
       delete state_;
@@ -157,10 +158,11 @@
         (callback)(state_->script_url(),
                    state_->function_name(),
                    state_->package_root(),
-                   state_->package_map(),
+                   state_->package_config(),
                    &api_flags,
                    state_->init_data(),
                    &error));
+    state_->DecrementSpawnCount();
     if (isolate == NULL) {
       ReportError(error);
       delete state_;
@@ -200,7 +202,17 @@
 };
 
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 7) {
+static const char* String2UTF8(const String& str) {
+  intptr_t len = Utf8::Length(str);
+  char* result = new char[len + 1];
+  str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
+  result[len] = 0;
+
+  return result;
+}
+
+
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 9) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(2));
@@ -208,6 +220,8 @@
   GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(4));
   GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
   GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
+  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(7));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8));
 
   if (closure.IsClosure()) {
     Function& func = Function::Handle();
@@ -221,21 +235,38 @@
       // Get the parent function so that we get the right function name.
       func = func.parent_function();
 
+      // Get the script URI so that we know what script to load.
+      const Library& root_lib = Library::Handle(zone,
+          isolate->object_store()->root_library());
+      const String& script_uri = String::Handle(zone, root_lib.url());
+
+      const char* utf8_package_root =
+          packageRoot.IsNull() ? NULL : String2UTF8(packageRoot);
+      const char* utf8_package_config =
+          packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
+
       bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
       Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
       Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
 
-      ThreadPool::Task* spawn_task =
-          new SpawnIsolateTask(
-              new IsolateSpawnState(port.Id(),
-                                    isolate->origin_id(),
-                                    isolate->init_callback_data(),
-                                    func,
-                                    message,
-                                    paused.value(),
-                                    fatal_errors,
-                                    on_exit_port,
-                                    on_error_port));
+      IsolateSpawnState* state =
+          new IsolateSpawnState(port.Id(),
+                                isolate->origin_id(),
+                                isolate->init_callback_data(),
+                                String2UTF8(script_uri),
+                                func,
+                                message,
+                                isolate->spawn_count_monitor(),
+                                isolate->spawn_count(),
+                                utf8_package_root,
+                                utf8_package_config,
+                                paused.value(),
+                                fatal_errors,
+                                on_exit_port,
+                                on_error_port);
+      ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
+
+      isolate->IncrementSpawnCount();
       if (FLAG_i_like_slow_isolate_spawn) {
         // We block the parent isolate while the child isolate loads.
         Isolate* saved = Isolate::Current();
@@ -244,8 +275,13 @@
         delete spawn_task;
         spawn_task = NULL;
         Thread::EnterIsolate(saved);
-      } else {
-        Dart::thread_pool()->Run(spawn_task);
+      } else if (!Dart::thread_pool()->Run(spawn_task)) {
+        // Running on the thread pool failed. Clean up everything.
+        state->DecrementSpawnCount();
+        delete state;
+        state = NULL;
+        delete spawn_task;
+        spawn_task = NULL;
       }
       return Object::null();
     }
@@ -257,16 +293,6 @@
 }
 
 
-static const char* String2UTF8(const String& str) {
-  intptr_t len = Utf8::Length(str);
-  char* result = new char[len + 1];
-  str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
-  result[len] = 0;
-
-  return result;
-}
-
-
 static const char* CanonicalizeUri(Thread* thread,
                                    const Library& library,
                                    const String& uri,
@@ -319,8 +345,8 @@
 
   GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
 
-  GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10));
-  GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11));
+  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
 
   if (Dart::IsRunningPrecompiledCode()) {
     const Array& args = Array::Handle(Array::New(1));
@@ -341,26 +367,9 @@
   }
 
   const char* utf8_package_root =
-      package_root.IsNull() ? NULL : String2UTF8(package_root);
-
-  const char** utf8_package_map = NULL;
-  if (!packages.IsNull()) {
-    intptr_t len = packages.Length();
-    utf8_package_map = new const char*[len + 1];
-
-    Object& entry = Object::Handle();
-    for (intptr_t i = 0; i < len; i++) {
-      entry = packages.At(i);
-      if (!entry.IsString()) {
-        const String& msg = String::Handle(String::NewFormatted(
-            "Bad value in package map: %s", entry.ToCString()));
-        ThrowIsolateSpawnException(msg);
-      }
-      utf8_package_map[i] = String2UTF8(String::Cast(entry));
-    }
-    // NULL terminated array.
-    utf8_package_map[len] = NULL;
-  }
+      packageRoot.IsNull() ? NULL : String2UTF8(packageRoot);
+  const char* utf8_package_config =
+      packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
 
   bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
   Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
@@ -372,9 +381,11 @@
           isolate->init_callback_data(),
           canonical_uri,
           utf8_package_root,
-          utf8_package_map,
+          utf8_package_config,
           args,
           message,
+          isolate->spawn_count_monitor(),
+          isolate->spawn_count(),
           paused.value(),
           fatal_errors,
           on_exit_port,
@@ -387,6 +398,8 @@
   }
 
   ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
+
+  isolate->IncrementSpawnCount();
   if (FLAG_i_like_slow_isolate_spawn) {
     // We block the parent isolate while the child isolate loads.
     Isolate* saved = Isolate::Current();
@@ -395,8 +408,13 @@
     delete spawn_task;
     spawn_task = NULL;
     Thread::EnterIsolate(saved);
-  } else {
-    Dart::thread_pool()->Run(spawn_task);
+  } else if (!Dart::thread_pool()->Run(spawn_task)) {
+    // Running on the thread pool failed. Clean up everything.
+    state->DecrementSpawnCount();
+    delete state;
+    state = NULL;
+    delete spawn_task;
+    spawn_task = NULL;
   }
   return Object::null();
 }
@@ -413,6 +431,13 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0) {
+  const Library& root_lib = Library::Handle(zone,
+      isolate->object_store()->root_library());
+  return root_lib.url();
+}
+
+
 DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1));
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index bb37371..de652ac 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -270,26 +270,63 @@
 
 patch class Isolate {
   static final _currentIsolate = _getCurrentIsolate();
+  static final _rootUri = _getCurrentRootUri();
 
   /* patch */ static Isolate get current => _currentIsolate;
 
+  /* patch */ static Future<Uri> get packageRoot {
+    var hook = VMLibraryHooks.packageRootUriFuture;
+    if (hook == null) {
+      throw new UnsupportedError("Isolate.packageRoot");
+    }
+    return hook();
+  }
+
+  /* patch */ static Future<Uri> get packageConfig {
+    var hook = VMLibraryHooks.packageConfigUriFuture;
+    if (hook == null) {
+      throw new UnsupportedError("Isolate.packageConfig");
+    }
+    return hook();
+  }
+
+  /* patch */ static Future<Uri> resolvePackageUri(Uri packageUri) {
+    var hook = VMLibraryHooks.resolvePackageUriFuture;
+    if (hook == null) {
+      throw new UnsupportedError("Isolate.resolvePackageUri");
+    }
+    return hook(packageUri);
+  }
+
+  static bool _packageSupported() =>
+      (VMLibraryHooks.packageRootUriFuture != null) &&
+      (VMLibraryHooks.packageConfigUriFuture != null);
+
   /* patch */ static Future<Isolate> spawn(
       void entryPoint(message), var message,
       {bool paused: false, bool errorsAreFatal,
-       SendPort onExit, SendPort onError}) {
+       SendPort onExit, SendPort onError}) async {
     // `paused` isn't handled yet.
     RawReceivePort readyPort;
     try {
       // The VM will invoke [_startIsolate] with entryPoint as argument.
       readyPort = new RawReceivePort();
+      var packageRoot = null;
+      var packageConfig = null;
+      if (Isolate._packageSupported()) {
+        packageRoot = (await Isolate.packageRoot)?.toString();
+        packageConfig = (await Isolate.packageConfig)?.toString();
+      }
+
       _spawnFunction(readyPort.sendPort, entryPoint, message,
-                     paused, errorsAreFatal, onExit, onError);
-      return _spawnCommon(readyPort);
+                     paused, errorsAreFatal, onExit, onError,
+                     packageRoot, packageConfig);
+      return await _spawnCommon(readyPort);
     } catch (e, st) {
       if (readyPort != null) {
         readyPort.close();
       }
-      return new Future<Isolate>.error(e, st);
+      return await new Future<Isolate>.error(e, st);
     }
   }
 
@@ -301,28 +338,63 @@
        bool errorsAreFatal,
        bool checked,
        Map<String, String> environment,
-       Uri packageRoot}) {
+       Uri packageRoot,
+       Uri packageConfig,
+       bool automaticPackageResolution: false}) async {
     RawReceivePort readyPort;
-    if (environment != null) throw new UnimplementedError("environment");
+    if (environment != null) {
+      throw new UnimplementedError("environment");
+    }
+
+    // Verify that no mutually exclusive arguments have been passed.
+    if (automaticPackageResolution) {
+      if (packageRoot != null) {
+        throw new ArgumentError("Cannot simultaneously request "
+                                "automaticPackageResolution and specify a"
+                                "packageRoot.");
+      }
+      if (packageConfig != null) {
+        throw new ArgumentError("Cannot simultaneously request "
+                                "automaticPackageResolution and specify a"
+                                "packageConfig.");
+      }
+    } else {
+      if ((packageRoot != null) && (packageConfig != null)) {
+        throw new ArgumentError("Cannot simultaneously specify a "
+                                "packageRoot and a packageConfig.");
+      }
+    }
     try {
+      // Resolve the uri agains the current isolate's root Uri first.
+      var spawnedUri = _rootUri.resolveUri(uri);
+
+      // Inherit this isolate's package resolution setup if not overridden.
+      if (!automaticPackageResolution &&
+          (packageRoot == null) &&
+          (packageConfig == null)) {
+        if (Isolate._packageSupported()) {
+          packageRoot = await Isolate.packageRoot;
+          packageConfig = await Isolate.packageConfig;
+        }
+      }
+
       // The VM will invoke [_startIsolate] and not `main`.
       readyPort = new RawReceivePort();
-      var packageRootString =
-          (packageRoot == null) ? null : packageRoot.toString();
-      var packagesList = null;
+      var packageRootString = packageRoot?.toString();
+      var packageConfigString = packageConfig?.toString();
 
-      _spawnUri(readyPort.sendPort, uri.toString(),
+      _spawnUri(readyPort.sendPort, spawnedUri.toString(),
                 args, message,
                 paused, onExit, onError,
                 errorsAreFatal, checked,
                 null, /* environment */
-                packageRootString, packagesList);
-      return _spawnCommon(readyPort);
+                packageRootString, packageConfigString);
+      return await _spawnCommon(readyPort);
     } catch (e, st) {
       if (readyPort != null) {
         readyPort.close();
       }
-      return new Future<Isolate>.error(e, st);
+      return await new Future<Isolate>.error(e, st);
     }
   }
 
@@ -366,7 +438,8 @@
 
   static void _spawnFunction(SendPort readyPort, Function topLevelFunction,
                              var message, bool paused, bool errorsAreFatal,
-                             SendPort onExit, SendPort onError)
+                             SendPort onExit, SendPort onError,
+                             String packageRoot, String packageConfig)
       native "Isolate_spawnFunction";
 
   static void _spawnUri(SendPort readyPort, String uri,
@@ -374,7 +447,7 @@
                         bool paused, SendPort onExit, SendPort onError,
                         bool errorsAreFatal, bool checked,
                         List environment,
-                        String packageRoot, List packages)
+                        String packageRoot, String packageConfig)
       native "Isolate_spawnUri";
 
   static void _sendOOB(port, msg) native "Isolate_sendOOB";
@@ -469,4 +542,15 @@
 
   static List _getPortAndCapabilitiesOfCurrentIsolate()
       native "Isolate_getPortAndCapabilitiesOfCurrentIsolate";
+
+  static Uri _getCurrentRootUri() {
+    try {
+      return Uri.parse(_getCurrentRootUriStr());
+    } catch (e, s) {
+      return null;
+    }
+  }
+
+  static String _getCurrentRootUriStr()
+      native "Isolate_getCurrentRootUriStr";
 }
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 24e6d71..05453f8 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1726,8 +1726,7 @@
   }
 
   const intptr_t num_explicit_args = explicit_args.Length();
-  const intptr_t num_implicit_args =
-      redirected_constructor.IsGenerativeConstructor() ? 2 : 1;
+  const intptr_t num_implicit_args = 1;
   const Array& args =
       Array::Handle(Array::New(num_implicit_args + num_explicit_args));
 
@@ -1758,9 +1757,9 @@
 
   Instance& new_object = Instance::Handle();
   if (redirected_constructor.IsGenerativeConstructor()) {
-    // Constructors get the uninitialized object and a constructor phase. Note
-    // we have delayed allocation until after the function type and argument
-    // matching checks.
+    // Constructors get the uninitialized object.
+    // Note we have delayed allocation until after the function
+    // type and argument matching checks.
     new_object = Instance::New(redirected_klass);
     if (!type_arguments.IsNull()) {
       // The type arguments will be null if the class has no type parameters, in
@@ -1769,7 +1768,6 @@
       new_object.SetTypeArguments(type_arguments);
     }
     args.SetAt(0, new_object);
-    args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Factories get type arguments.
     args.SetAt(0, type_arguments);
diff --git a/runtime/observatory/lib/src/elements/instance_ref.html b/runtime/observatory/lib/src/elements/instance_ref.html
index 7125f16..385727b 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.html
+++ b/runtime/observatory/lib/src/elements/instance_ref.html
@@ -106,8 +106,8 @@
                                  expandKey="{{ makeExpandKey('value') }}">
               </any-service-ref><br>
             </template>
-            <template if="{{ ref.length != ref.association.length }}">
-              <div><em>{{ ref.length - ref.association.length }} omitted association</em></div>
+            <template if="{{ ref.length != ref.associations.length }}">
+              <div><em>{{ ref.length - ref.associations.length }} omitted associations</em></div>
             </template>
           </div>
         </curly-block>
diff --git a/runtime/observatory/tests/service/async_next_test.dart b/runtime/observatory/tests/service/async_next_test.dart
index 9e298f7..f3c64d9 100644
--- a/runtime/observatory/tests/service/async_next_test.dart
+++ b/runtime/observatory/tests/service/async_next_test.dart
@@ -25,6 +25,7 @@
 }
 
 asyncNext(Isolate isolate) async {
+  print('asyncNext');
   return isolate.asyncStepOver()[Isolate.kSecondResume];
 }
 
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index b558c46..0255687 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -11,7 +11,7 @@
 int globalVar = 100;
 
 class MyClass {
-       static       void myFunction(int value) {
+  static void myFunction(int value) {
     if (value < 0) {
       print("negative");
     } else {
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
new file mode 100644
index 0000000..71345ee
--- /dev/null
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2016, 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+
+int globalVar = 100;
+
+class MyClass {
+  static void myFunction(int value) {
+    if (value < 0) {
+      print("negative");
+    } else {
+      print("positive");
+    }
+    debugger();
+  }
+
+  static void otherFunction(int value) {
+    if (value < 0) {
+      print("otherFunction <");
+    } else {
+      print("otherFunction >=");
+    }
+  }
+}
+
+void testFunction() {
+  MyClass.otherFunction(-100);
+  MyClass.myFunction(10000);
+}
+
+bool allRangesCompiled(coverage) {
+  for (int i = 0; i < coverage['ranges'].length; i++) {
+    if (!coverage['ranges'][i]['compiled']) {
+      return false;
+    }
+  }
+  return true;
+}
+
+var tests = [
+
+hasStoppedAtBreakpoint,
+
+(Isolate isolate) async {
+  var stack = await isolate.getStack();
+
+  // Make sure we are in the right place.
+  expect(stack.type, equals('Stack'));
+  expect(stack['frames'].length, greaterThanOrEqualTo(2));
+  expect(stack['frames'][0].function.name, equals('myFunction'));
+  expect(stack['frames'][0].function.dartOwner.name, equals('MyClass'));
+
+  var func = stack['frames'][0].function;
+  expect(func.name, equals('myFunction'));
+  await func.load();
+
+  var expectedRange = {
+    'scriptIndex': 0,
+    'startPos': 33,
+    'endPos': 82,
+    'compiled': true,
+    'coverage': {'hits': [48, 66, 76], 'misses': [54]}
+  };
+
+  // Full script
+  var params = { 'reports' : ['Coverage'],
+                 'scriptId' : func.location.script.id };
+  var coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 6);
+  expect(coverage['ranges'][0], equals(expectedRange));
+  expect(coverage['scripts'].length, 1);
+  expect(coverage['scripts'][0]['uri'],
+         endsWith('get_source_report_test.dart'));
+  expect(allRangesCompiled(coverage), isFalse);
+
+  // Force compilation.
+  params = { 'reports' : ['Coverage'],
+             'scriptId' : func.location.script.id,
+             'forceCompile' : true };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 6);
+  expect(allRangesCompiled(coverage), isTrue);
+
+  // One function
+  params = { 'reports' : ['Coverage'],
+             'scriptId' : func.location.script.id,
+             'tokenPos' : func.location.tokenPos,
+             'endTokenPos' : func.location.endTokenPos };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 1);
+  expect(coverage['ranges'][0], equals(expectedRange));
+  expect(coverage['scripts'].length, 1);
+  expect(coverage['scripts'][0]['uri'],
+         endsWith('get_source_report_test.dart'));
+
+  // Full isolate
+  params = { 'reports' : ['Coverage'] };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, greaterThan(1));
+  expect(coverage['scripts'].length, greaterThan(1));
+
+  // Multiple reports (make sure enum list parameter parsing works).
+  params = { 'reports' : ['CallSites', 'Coverage'],
+             'scriptId' : func.location.script.id,
+             'tokenPos' : func.location.tokenPos,
+             'endTokenPos' : func.location.endTokenPos };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 1);
+  var range = coverage['ranges'][0];
+  expect(range.containsKey('callSites'), isTrue);
+  expect(range.containsKey('coverage'), isTrue);
+
+  // missing scriptId with tokenPos.
+  bool caughtException = false;
+  try {
+    params = { 'reports' : ['Coverage'],
+               'tokenPos' : func.location.tokenPos };
+    coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  } on ServerRpcException catch(e) {
+    caughtException = true;
+    expect(e.code, equals(ServerRpcException.kInvalidParams));
+    expect(e.message,
+           "_getSourceReport: the 'tokenPos' parameter requires the "
+           "\'scriptId\' parameter");
+  }
+  expect(caughtException, isTrue);
+
+  // missing scriptId with endTokenPos.
+  caughtException = false;
+  try {
+    params = { 'reports' : ['Coverage'],
+               'endTokenPos' : func.location.endTokenPos };
+    coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  } on ServerRpcException catch(e) {
+    caughtException = true;
+    expect(e.code, equals(ServerRpcException.kInvalidParams));
+    expect(e.message,
+           "_getSourceReport: the 'endTokenPos' parameter requires the "
+           "\'scriptId\' parameter");
+  }
+  expect(caughtException, isTrue);
+},
+
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/tcp_socket_service_test.dart b/runtime/observatory/tests/service/tcp_socket_service_test.dart
index f8dff03..c80cad5 100644
--- a/runtime/observatory/tests/service/tcp_socket_service_test.dart
+++ b/runtime/observatory/tests/service/tcp_socket_service_test.dart
@@ -36,6 +36,9 @@
     //   The server socket accepting connections, on port X
     //   The accepted connection on the client, on port Y
     //   The client connection, on port X
+    if (result['data'].length != 5) {
+      print(result['data']);
+    }
     expect(result['data'].length, equals(5));
     // The first socket will have a name like listening:127.0.0.1:X
     // The second will have a name like 127.0.0.1:Y
diff --git a/runtime/platform/assert.cc b/runtime/platform/assert.cc
index 41f42f4..e9d1c4f 100644
--- a/runtime/platform/assert.cc
+++ b/runtime/platform/assert.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "platform/globals.h"
+#include "vm/os.h"
 
 namespace dart {
 
@@ -38,7 +39,7 @@
   // TODO(5411324): replace std::abort with OS::Abort so that we can handle
   // restoring of signal handlers before aborting.
   if (kind_ == ASSERT) {
-    abort();
+    OS::Abort();
   }
   static bool failed = false;
   if (!failed) {
diff --git a/runtime/tests/vm/dart/spawn_shutdown_test.dart b/runtime/tests/vm/dart/spawn_shutdown_test.dart
index 238c325..13fb2b8e2 100644
--- a/runtime/tests/vm/dart/spawn_shutdown_test.dart
+++ b/runtime/tests/vm/dart/spawn_shutdown_test.dart
@@ -14,6 +14,15 @@
 // workers in a staggered fashion in an attempt to see a variety of
 // isolate states at the time that this program terminates.
 
+trySpawn(Function f, Object o) async {
+  try {
+    await Isolate.spawn(f, o);
+  } catch (e) {
+    // Isolate spawning may fail if the program is ending.
+    assert(e is IsolateSpawnException);
+  }
+}
+
 void worker(SendPort parentPort) {
   var port = new RawReceivePort();
 
@@ -26,7 +35,7 @@
   }
 
   // Spawn a child worker.
-  Isolate.spawn(worker, port.sendPort);
+  trySpawn(worker, port.sendPort);
 }
 
 void main() {
@@ -39,7 +48,7 @@
   // variety of states when the vm shuts down.
   print('Starting ${numWorkers} workers...');
   for (int i = 0; i < numWorkers; i++) {
-    Isolate.spawn(worker, null);
+    trySpawn(worker, null);
     sleep(delay);
   }
 
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 7a914be..f0bc1ef 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -14,8 +14,6 @@
 
 dart/data_uri_import_test/none: SkipByDesign
 
-dart/spawn_shutdown_test: Skip # Issue 25351
-
 [ $mode == debug ]
 # This is a benchmark that is not informative in debug mode.
 cc/CorelibIsolateStartup: Skip
@@ -88,8 +86,8 @@
 
 [ $noopt || $compiler == precompiler ]
 dart/redirection_type_shuffling_test: CompileTimeError # Imports dart:mirrors
-dart/inline_stack_frame_test: Fail  # Issue 24783 - inlined frames missing
+dart/optimized_stacktrace_test: RuntimeError # Expects line and column numbers
 
 [ $runtime == dart_precompiled ]
-dart/optimized_stacktrace_test: Fail
+dart/inline_stack_frame_test: Fail  # Issue 24783 - inlined frames missing
 dart/data_uri_spawn_test: RuntimeError # Isolate.spawnUri
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index 4e1eca9..f5358c1 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -13,6 +13,12 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, disassemble);
+DECLARE_FLAG(bool, disassemble_optimized);
+
+DEFINE_FLAG(bool, check_code_pointer, false,
+            "Verify instructions offset in code object."
+            "NOTE: This breaks the profiler.");
 DEFINE_FLAG(bool, code_comments, false,
             "Include comments into code and disassembly");
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
@@ -20,9 +26,6 @@
             "Enable far branches for ARM and MIPS");
 #endif
 
-DECLARE_FLAG(bool, disassemble);
-DECLARE_FLAG(bool, disassemble_optimized);
-
 static uword NewContents(intptr_t capacity) {
   Zone* zone = Thread::Current()->zone();
   uword result = zone->AllocUnsafe(capacity);
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index d31948a..e74a8c8 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -22,9 +22,11 @@
 namespace dart {
 
 DECLARE_FLAG(bool, allow_absolute_addresses);
-DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 
+DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+
 uint32_t Address::encoding3() const {
   if (kind_ == Immediate) {
     uint32_t offset = encoding_ & kOffset12Mask;
@@ -1518,6 +1520,9 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
   Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(R0);
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 062ad4b..59c85c3 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -22,9 +22,11 @@
 namespace dart {
 
 DECLARE_FLAG(bool, allow_absolute_addresses);
+DECLARE_FLAG(bool, check_code_pointer);
+DECLARE_FLAG(bool, inline_alloc);
+
 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");
 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
-DECLARE_FLAG(bool, inline_alloc);
 
 
 Assembler::Assembler(bool use_far_branches)
@@ -1081,6 +1083,9 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
   Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(R0);
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 0f15e3f..957b549 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -14,12 +14,14 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, allow_absolute_addresses);
+DECLARE_FLAG(bool, check_code_pointer);
+DECLARE_FLAG(bool, inline_alloc);
 #if defined(USING_SIMULATOR)
 DECLARE_FLAG(int, trace_sim_after);
 #endif
-DECLARE_FLAG(bool, allow_absolute_addresses);
+
 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
-DECLARE_FLAG(bool, inline_alloc);
 
 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
   ASSERT(Utils::IsAligned(data, 4));
@@ -461,6 +463,9 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
   Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(CMPRES1);
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 85b83a9..02527fc 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -18,9 +18,11 @@
 namespace dart {
 
 DECLARE_FLAG(bool, allow_absolute_addresses);
-DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 
+DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+
 
 Assembler::Assembler(bool use_far_branches)
     : buffer_(),
@@ -3372,6 +3374,9 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
   Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   pushq(RAX);
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 0b585d5..19542b3 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -6,14 +6,21 @@
 #include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/isolate.h"
+#include "vm/log.h"
 #include "vm/object_store.h"
 #include "vm/resolver.h"
 
 
 namespace dart {
 
+DEFINE_FLAG(bool, trace_ast_visitor, false,
+            "Trace AstVisitor.");
+
 #define DEFINE_VISIT_FUNCTION(BaseName)                                        \
 void BaseName##Node::Visit(AstNodeVisitor* visitor) {                          \
+  if (FLAG_trace_ast_visitor) {                                                \
+    THR_Print("Visiting %s\n", PrettyName());                                  \
+  }                                                                            \
   visitor->Visit##BaseName##Node(this);                                        \
 }
 
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 0e9b68c..01ae0cf 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -99,7 +99,7 @@
  public:
   explicit AstNode(intptr_t token_pos)
       : token_pos_(token_pos) {
-    ASSERT(token_pos_ >= 0);
+    ASSERT(Scanner::ValidSourcePosition(token_pos_));
   }
   virtual ~AstNode() { }
 
@@ -212,8 +212,10 @@
 //   <AwaitMarker> -> ...
 class AwaitMarkerNode : public AstNode {
  public:
-  AwaitMarkerNode(LocalScope* async_scope, LocalScope* await_scope)
-    : AstNode(Scanner::kNoSourcePos),
+  AwaitMarkerNode(LocalScope* async_scope,
+                  LocalScope* await_scope,
+                  intptr_t token_pos)
+    : AstNode(token_pos),
       async_scope_(async_scope),
       await_scope_(await_scope) {
     ASSERT(async_scope != NULL);
@@ -1921,13 +1923,15 @@
                const LocalVariable* context_var,
                CatchClauseNode* catch_block,
                SequenceNode* finally_block,
-               intptr_t try_index)
+               intptr_t try_index,
+               SequenceNode* rethrow_clause)
       : AstNode(token_pos),
         try_block_(try_block),
         context_var_(*context_var),
         catch_block_(catch_block),
         finally_block_(finally_block),
-        try_index_(try_index) {
+        try_index_(try_index),
+        rethrow_clause_(rethrow_clause) {
     ASSERT(try_block_ != NULL);
     ASSERT(context_var != NULL);
     ASSERT(catch_block_ != NULL);
@@ -1939,6 +1943,8 @@
   const LocalVariable& context_var() const { return context_var_; }
   intptr_t try_index() const { return try_index_; }
 
+  SequenceNode* rethrow_clause() const { return rethrow_clause_; }
+
   virtual void VisitChildren(AstNodeVisitor* visitor) const {
     try_block_->Visit(visitor);
     if (catch_block_ != NULL) {
@@ -1957,6 +1963,7 @@
   CatchClauseNode* catch_block_;
   SequenceNode* finally_block_;
   const intptr_t try_index_;
+  SequenceNode* rethrow_clause_;
 
   DISALLOW_COPY_AND_ASSIGN(TryCatchNode);
 };
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index ae42b70..32ec3f9 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -119,6 +119,7 @@
   //   :saved_try_ctx_var = :await_saved_try_ctx_var_y;
   //   :await_temp_var_(X+1) = :result_param;
 
+  const intptr_t token_pos = node->token_pos();
   LocalVariable* async_op = GetVariableInScope(
       preamble_->scope(), Symbols::AsyncOperation());
   LocalVariable* async_then_callback = GetVariableInScope(
@@ -136,7 +137,7 @@
   LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr);
 
   AwaitMarkerNode* await_marker =
-      new (Z) AwaitMarkerNode(async_temp_scope_, node->scope());
+      new (Z) AwaitMarkerNode(async_temp_scope_, node->scope(), token_pos);
   preamble_->Add(await_marker);
 
   // :result_param = _awaitHelper(
diff --git a/runtime/vm/atomic.h b/runtime/vm/atomic.h
index 9d1fd13..809548a 100644
--- a/runtime/vm/atomic.h
+++ b/runtime/vm/atomic.h
@@ -33,6 +33,8 @@
   //
   // NOTE: OK to use with memory locations that are accessed by generated code
   static uword CompareAndSwapWord(uword* ptr, uword old_value, uword new_value);
+  static uint32_t CompareAndSwapUint32(
+      uint32_t* ptr, uint32_t old_value, uint32_t new_value);
 
   // Performs a load of a word from 'ptr', but without any guarantees about
   // memory order (i.e., no load barriers/fences).
diff --git a/runtime/vm/atomic_android.h b/runtime/vm/atomic_android.h
index 9f4df90..8d01ae7 100644
--- a/runtime/vm/atomic_android.h
+++ b/runtime/vm/atomic_android.h
@@ -32,6 +32,13 @@
                                                   uword new_value) {
   return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_linux.h b/runtime/vm/atomic_linux.h
index dc57f2d..1150857 100644
--- a/runtime/vm/atomic_linux.h
+++ b/runtime/vm/atomic_linux.h
@@ -32,6 +32,13 @@
                                                   uword new_value) {
   return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_macos.h b/runtime/vm/atomic_macos.h
index b56d2a0..31d219b 100644
--- a/runtime/vm/atomic_macos.h
+++ b/runtime/vm/atomic_macos.h
@@ -32,6 +32,13 @@
                                                   uword new_value) {
   return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_simulator.h b/runtime/vm/atomic_simulator.h
index 26cde3c..2b52a22 100644
--- a/runtime/vm/atomic_simulator.h
+++ b/runtime/vm/atomic_simulator.h
@@ -18,6 +18,13 @@
                                                   uword new_value) {
   return Simulator::CompareExchange(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return Simulator::CompareExchangeUint32(ptr, old_value, new_value);
+}
 #endif  // defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_test.cc b/runtime/vm/atomic_test.cc
index 5e22606..2e327a5 100644
--- a/runtime/vm/atomic_test.cc
+++ b/runtime/vm/atomic_test.cc
@@ -31,4 +31,22 @@
   EXPECT_EQ(static_cast<uword>(42), AtomicOperations::LoadRelaxed(&v));
 }
 
+
+TEST_CASE(CompareAndSwapWord) {
+  uword old_value = 42;
+  uword new_value = 100;
+  uword result = AtomicOperations::CompareAndSwapWord(
+      &old_value, old_value, new_value);
+  EXPECT_EQ(static_cast<uword>(42), result);
+}
+
+
+TEST_CASE(CompareAndSwapUint32) {
+  uint32_t old_value = 42;
+  uint32_t new_value = 100;
+  uint32_t result = AtomicOperations::CompareAndSwapUint32(
+      &old_value, old_value, new_value);
+  EXPECT_EQ(static_cast<uint32_t>(42), result);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/atomic_win.h b/runtime/vm/atomic_win.h
index 4ef539c..8e07cd3 100644
--- a/runtime/vm/atomic_win.h
+++ b/runtime/vm/atomic_win.h
@@ -59,6 +59,18 @@
 #error Unsupported host architecture.
 #endif
 }
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+#if (defined(HOST_ARCH_X64) || defined(HOST_ARCH_IA32))
+  return static_cast<uint32_t>(
+      InterlockedCompareExchange(reinterpret_cast<LONG*>(ptr),
+                                 static_cast<LONG>(new_value),
+                                 static_cast<LONG>(old_value)));
+#else
+#error Unsupported host architecture.
+#endif
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index a3b3952..036f460 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -311,9 +311,10 @@
   V(Int32x4_setFlagZ, 2)                                                       \
   V(Int32x4_setFlagW, 2)                                                       \
   V(Int32x4_select, 3)                                                         \
-  V(Isolate_spawnFunction, 7)                                                  \
+  V(Isolate_spawnFunction, 9)                                                  \
   V(Isolate_spawnUri, 12)                                                      \
   V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0)                         \
+  V(Isolate_getCurrentRootUriStr, 0)                                           \
   V(Isolate_sendOOB, 2)                                                        \
   V(Mirrors_evalInLibraryWithPrivateKey, 2)                                    \
   V(Mirrors_makeLocalClassMirror, 1)                                           \
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index ebe15cf..e24e186 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -102,6 +102,7 @@
       AddPlaceHolder();
     }
     list_[try_index].outer_try_index = outer_try_index;
+    ASSERT(list_[try_index].pc_offset == ExceptionHandlers::kInvalidPcOffset);
     list_[try_index].pc_offset = pc_offset;
     ASSERT(handler_types.IsZoneHandle());
     list_[try_index].handler_types = &handler_types;
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index 2cdc6fb..bea6025 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -20,7 +20,7 @@
 
 namespace dart {
 
-static const intptr_t kPos = Scanner::kNoSourcePos;
+static const intptr_t kPos = 0;
 
 
 CODEGEN_TEST_GENERATE(SimpleReturnCodegen, test) {
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index be9c996..70d1ac6 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1049,8 +1049,10 @@
         TimelineDurationScope tds(thread(),
                                   compiler_timeline,
                                   "FinalizeCompilation");
-        // This part of compilation must be at a safepoint.
-        if (!thread()->IsMutatorThread()) {
+        if (thread()->IsMutatorThread()) {
+          FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
+        } else {
+          // This part of compilation must be at a safepoint.
           // Stop mutator thread before creating the instruction object and
           // installing code.
           // Mutator thread may not run code while we are creating the
@@ -1058,13 +1060,16 @@
           // changes code page access permissions (makes them temporary not
           // executable).
           isolate()->thread_registry()->SafepointThreads();
-        }
-
-        FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
-
-        if (!thread()->IsMutatorThread()) {
-          // Background compilation.
+          {
+            // Do not Garbage collect during this stage and instead allow the
+            // heap to grow.
+            NoHeapGrowthControlScope no_growth_control;
+            FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
+          }
           isolate()->thread_registry()->ResumeAllThreads();
+          if (isolate()->heap()->NeedsGarbageCollection()) {
+            isolate()->heap()->CollectAllGarbage();
+          }
         }
       }
       // Mark that this isolate now has compiled code.
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index 8792cf5..695c23c 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -743,7 +743,7 @@
   const Object& value = def->constant_value();
   if (IsNonConstant(value)) {
     const AbstractType& checked_type = instr->type();
-    intptr_t value_cid = instr->value()->Type()->ToCid();
+    intptr_t value_cid = instr->value()->definition()->Type()->ToCid();
     Representation rep = def->representation();
     if ((checked_type.IsFloat32x4Type() && (rep == kUnboxedFloat32x4)) ||
         (checked_type.IsInt32x4Type() && (rep == kUnboxedInt32x4)) ||
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index b14ce55..913a69c 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -25,18 +25,18 @@
   R12 = 12,
   R13 = 13,
   R14 = 14,
-  R15 = 15,
+  R15 = 15,  // SP in Dart code.
   R16 = 16,  // IP0 aka TMP
   R17 = 17,  // IP1 aka TMP2
   R18 = 18,  // "platform register" on iOS.
-  R19 = 19,  // SP in Dart code.
-  R20 = 20,  // THR
+  R19 = 19,
+  R20 = 20,
   R21 = 21,
   R22 = 22,
   R23 = 23,
   R24 = 24,
   R25 = 25,
-  R26 = 26,
+  R26 = 26,  // THR
   R27 = 27,  // PP
   R28 = 28,  // CTX
   R29 = 29,  // FP
@@ -53,7 +53,7 @@
   // Aliases.
   IP0 = R16,
   IP1 = R17,
-  SP = R19,
+  SP = R15,
   FP = R29,
   LR = R30,
 };
@@ -112,11 +112,11 @@
 const Register PP = R27;  // Caches object pool pointer in generated code.
 const Register CODE_REG = R24;
 const Register FPREG = FP;  // Frame pointer register.
-const Register SPREG = R19;  // Stack pointer register.
+const Register SPREG = R15;  // Stack pointer register.
 const Register LRREG = LR;  // Link register.
 const Register ICREG = R5;  // IC data register.
 const Register ARGS_DESC_REG = R4;  // Arguments descriptor register.
-const Register THR = R20;  // Caches current thread in generated code.
+const Register THR = R26;  // Caches current thread in generated code.
 
 
 // Exception object is passed in this register to the catch handlers when an
@@ -143,12 +143,12 @@
     (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
     (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7);
 const RegList kAbiPreservedCpuRegs =
-    (1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) |
-    (1 << R24) | (1 << R25) | (1 << R26) | (1 << R27) |
-    (1 << R28);
-const Register kAbiFirstPreservedCpuReg = R20;
+    (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
+    (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) |
+    (1 << R27) | (1 << R28);
+const Register kAbiFirstPreservedCpuReg = R19;
 const Register kAbiLastPreservedCpuReg = R28;
-const int kAbiPreservedCpuRegCount = 9;
+const int kAbiPreservedCpuRegCount = 10;
 const VRegister kAbiFirstPreservedFpuReg = V8;
 const VRegister kAbiLastPreservedFpuReg = V15;
 const int kAbiPreservedFpuRegCount = 8;
@@ -172,8 +172,8 @@
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
 const Register kDartFirstVolatileCpuReg = R0;
-const Register kDartLastVolatileCpuReg = R15;
-const int kDartVolatileCpuRegCount = 16;
+const Register kDartLastVolatileCpuReg = R14;
+const int kDartVolatileCpuRegCount = 15;
 const int kDartVolatileFpuRegCount = 24;
 
 static inline Register ConcreteRegister(Register r) {
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index fdb1d53..796aaca 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1266,6 +1266,7 @@
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
   CHECK_ISOLATE(I);
+  I->WaitForOutstandingSpawns();
   {
     StackZone zone(T);
     HandleScope handle_scope(T);
@@ -1341,23 +1342,6 @@
 }
 
 
-// TODO(iposva): Remove this API and instead expose the underlying flags.
-DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value) {
-  CHECK_ISOLATE(Isolate::Current());
-  Isolate* isolate = Isolate::Current();
-  if (isolate->has_compiled_code()) {
-    return Api::NewError(
-        "%s expects that the isolate has not yet compiled code.", CURRENT_FUNC);
-  }
-  if (!value) {
-    return Api::NewError(
-        "%s expects that the value is set to true only.", CURRENT_FUNC);
-  }
-  Isolate::Current()->set_strict_compilation();
-  return Api::Null();
-}
-
-
 static uint8_t* ApiReallocate(uint8_t* ptr,
                               intptr_t old_size,
                               intptr_t new_size) {
@@ -2747,10 +2731,9 @@
   }
   Instance& exception = Instance::Handle(zone);
   exception = Instance::New(cls);
-  const Array& args = Array::Handle(zone, Array::New(3));
+  const Array& args = Array::Handle(zone, Array::New(2));
   args.SetAt(0, exception);
-  args.SetAt(1, Smi::Handle(zone, Smi::New(Function::kCtorPhaseAll)));
-  args.SetAt(2, String::Handle(String::New(exception_message)));
+  args.SetAt(1, String::Handle(String::New(exception_message)));
   result = DartEntry::InvokeFunction(constructor, args);
   if (result.IsError()) return result.raw();
   ASSERT(result.IsNull());
@@ -3604,7 +3587,7 @@
       return ApiError::New(message);
     }
   }
-  int extra_args = (constructor.IsGenerativeConstructor() ? 2 : 1);
+  int extra_args = 1;
   String& error_message = String::Handle();
   if (!constructor.AreValidArgumentCounts(num_args + extra_args,
                                           0,
@@ -3718,11 +3701,11 @@
 
   // Create the argument list.
   intptr_t arg_index = 0;
-  int extra_args = (constructor.IsGenerativeConstructor() ? 2 : 1);
+  int extra_args = 1;
   const Array& args =
       Array::Handle(Z, Array::New(number_of_arguments + extra_args));
   if (constructor.IsGenerativeConstructor()) {
-    // Constructors get the uninitialized object and a constructor phase.
+    // Constructors get the uninitialized object.
     if (!type_arguments.IsNull()) {
       // The type arguments will be null if the class has no type parameters, in
       // which case the following call would fail because there is no slot
@@ -3730,7 +3713,6 @@
       new_object.SetTypeArguments(type_arguments);
     }
     args.SetAt(arg_index++, new_object);
-    args.SetAt(arg_index++, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Factories get type arguments.
     args.SetAt(arg_index++, type_arguments);
@@ -3922,14 +3904,14 @@
       TypeArguments::Handle(Z, type_obj.arguments());
   const Function& constructor =
       Function::Handle(Z, cls.LookupFunctionAllowPrivate(dot_name));
-  const int extra_args = 2;
+  const int extra_args = 1;
   if (!constructor.IsNull() &&
       constructor.IsGenerativeConstructor() &&
       constructor.AreValidArgumentCounts(number_of_arguments + extra_args,
                                          0,
                                          NULL)) {
     // Create the argument list.
-    // Constructors get the uninitialized object and a constructor phase.
+    // Constructors get the uninitialized object.
     if (!type_arguments.IsNull()) {
       // The type arguments will be null if the class has no type
       // parameters, in which case the following call would fail
@@ -3943,7 +3925,6 @@
         T, number_of_arguments, arguments, extra_args, &args);
     if (!::Dart_IsError(result)) {
       args.SetAt(0, instance);
-      args.SetAt(1, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll)));
       const Object& retval = Object::Handle(Z,
           DartEntry::InvokeFunction(constructor, args));
       if (retval.IsError()) {
@@ -5901,6 +5882,29 @@
 }
 
 
+#if defined(DART_PRECOMPILED)
+
+DART_EXPORT Dart_Handle Dart_Precompile(
+    Dart_QualifiedFunctionName entry_points[],
+    bool reset_fields) {
+  UNREACHABLE();
+  return 0;
+}
+
+
+DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshot(
+    uint8_t** vm_isolate_snapshot_buffer,
+    intptr_t* vm_isolate_snapshot_size,
+    uint8_t** isolate_snapshot_buffer,
+    intptr_t* isolate_snapshot_size,
+    uint8_t** instructions_snapshot_buffer,
+    intptr_t* instructions_snapshot_size) {
+  UNREACHABLE();
+  return 0;
+}
+
+#else  // DART_PRECOMPILED
+
 DART_EXPORT Dart_Handle Dart_Precompile(
     Dart_QualifiedFunctionName entry_points[],
     bool reset_fields) {
@@ -5973,6 +5977,7 @@
 
   return Api::Success();
 }
+#endif  // DART_PRECOMPILED
 
 
 DART_EXPORT bool Dart_IsRunningPrecompiledCode() {
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 3cbf287..a2cf1d3 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -254,7 +254,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(2, line_number);
-  EXPECT_EQ(3, column_number);
+  EXPECT_EQ(13, column_number);
 
   // Out-of-bounds frames.
   result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
@@ -3341,7 +3341,7 @@
 }
 
 
-TEST_CASE(IsolateSetCheckedMode) {
+UNIT_TEST_CASE(IsolateSetCheckedMode) {
   const char* kScriptChars =
       "int bad1() {\n"
       "  int foo = 'string';\n"
@@ -3352,23 +3352,49 @@
       "  int five = 5;\n"
       "  return five;"
       "}\n";
-  Dart_Handle result;
 
-  // Create a test library and Load up a test script in it.
-  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  result = Dart_IsolateSetStrictCompilation(true);
-  EXPECT_VALID(result);
+  // Create an isolate with checked mode flags.
+  Dart_IsolateFlags api_flags;
+  api_flags.version = DART_FLAGS_CURRENT_VERSION;
+  api_flags.enable_type_checks = true;
+  api_flags.enable_asserts = true;
+  api_flags.enable_error_on_bad_type = true;
+  api_flags.enable_error_on_bad_override = true;
 
-  result = Dart_Invoke(lib, NewString("bad1"), 0, NULL);
-  EXPECT_ERROR(result, "Unhandled exception:\n"
-      "type 'String' is not a subtype of type 'int' of 'foo'");
+  char* err;
+  Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL,
+                                            bin::isolate_snapshot_buffer,
+                                            &api_flags,
+                                            NULL, &err);
+  if (isolate == NULL) {
+    OS::Print("Creation of isolate failed '%s'\n", err);
+    free(err);
+  }
+  EXPECT(isolate != NULL);
 
-  result = Dart_Invoke(lib, NewString("good1"), 0, NULL);
-  EXPECT_VALID(result);
+  {
+    Dart_EnterScope();
+    Dart_Handle url = NewString(TestCase::url());
+    Dart_Handle source = NewString(kScriptChars);
+    Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler);
+    EXPECT_VALID(result);
+    Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
+    EXPECT_VALID(lib);
+    result = Dart_FinalizeLoading(false);
+    EXPECT_VALID(result);
+    result = Dart_Invoke(lib, NewString("bad1"), 0, NULL);
+    EXPECT_ERROR(result, "Unhandled exception:\n"
+        "type 'String' is not a subtype of type 'int' of 'foo'");
 
-  result = Dart_IsolateSetStrictCompilation(false);
-  EXPECT_ERROR(result, "Dart_IsolateSetStrictCompilation expects that the "
-                       "isolate has not yet compiled code.");
+    result = Dart_Invoke(lib, NewString("good1"), 0, NULL);
+    EXPECT_VALID(result);
+    Dart_ExitScope();
+  }
+
+  EXPECT(isolate != NULL);
+
+  // Shutdown the isolate.
+  Dart_ShutdownIsolate();
 }
 
 
@@ -7259,7 +7285,7 @@
 static Dart_Isolate RunLoopTestCallback(const char* script_name,
                                         const char* main,
                                         const char* package_root,
-                                        const char** package_map,
+                                        const char* package_config,
                                         Dart_IsolateFlags* flags,
                                         void* data,
                                         char** error) {
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index de926bf..abb3e5d 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -411,13 +411,11 @@
   const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
   ASSERT(!cls.IsNull());
   // For now, we only support a non-parameterized or raw type.
-  const int kNumExtraArgs = 2;  // implicit rcvr and construction phase args.
+  const int kNumExtraArgs = 1;  // implicit rcvr arg.
   const Instance& exception_object = Instance::Handle(Instance::New(cls));
   const Array& constructor_arguments =
     Array::Handle(Array::New(arguments.Length() + kNumExtraArgs));
   constructor_arguments.SetAt(0, exception_object);
-  constructor_arguments.SetAt(
-      1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   Object& obj = Object::Handle();
   for (intptr_t i = 0; i < arguments.Length(); i++) {
     obj = arguments.At(i);
diff --git a/runtime/vm/dart_entry_test.cc b/runtime/vm/dart_entry_test.cc
index 5f939ed..a661d5b 100644
--- a/runtime/vm/dart_entry_test.cc
+++ b/runtime/vm/dart_entry_test.cc
@@ -89,10 +89,8 @@
 
   // Invoke the constructor.
   const Instance& instance = Instance::Handle(Instance::New(cls));
-  const Array& constructor_arguments = Array::Handle(Array::New(2));
+  const Array& constructor_arguments = Array::Handle(Array::New(1));
   constructor_arguments.SetAt(0, instance);
-  constructor_arguments.SetAt(
-      1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   String& constructor_name = String::Handle(Symbols::New("A."));
   Function& constructor =
     Function::Handle(cls.LookupConstructor(constructor_name));
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 9ba75da..c533e3b 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -93,8 +93,8 @@
                                        intptr_t requested_column_number)
     : script_(Script::null()),
       url_(url.raw()),
-      token_pos_(-1),
-      end_token_pos_(-1),
+      token_pos_(Scanner::kNoSourcePos),
+      end_token_pos_(Scanner::kNoSourcePos),
       is_resolved_(false),
       next_(NULL),
       conditions_(NULL),
@@ -239,7 +239,7 @@
       code_(Code::ZoneHandle(code.raw())),
       function_(Function::ZoneHandle(code.function())),
       token_pos_initialized_(false),
-      token_pos_(-1),
+      token_pos_(Scanner::kNoSourcePos),
       try_index_(-1),
       line_number_(-1),
       column_number_(-1),
@@ -1740,7 +1740,7 @@
   PcDescriptors::Iterator iter(desc, kSafepointKind);
   while (iter.MoveNext()) {
     const intptr_t pos = iter.TokenPos();
-    if ((pos == Scanner::kNoSourcePos) ||
+    if ((pos < 0) ||
         (pos < requested_token_pos) ||
         (pos > last_token_pos)) {
       // Token is not in the target range.
@@ -1786,7 +1786,7 @@
     PcDescriptors::Iterator iter(desc, kSafepointKind);
     while (iter.MoveNext()) {
       const intptr_t pos = iter.TokenPos();
-      if ((pos == Scanner::kNoSourcePos) ||
+      if ((pos < 0) ||
           (pos < begin_pos) ||
           (pos > end_of_line_pos)) {
         // Token is not on same line as best fit.
@@ -1827,7 +1827,7 @@
 
 void Debugger::MakeCodeBreakpointAt(const Function& func,
                                     BreakpointLocation* loc) {
-  ASSERT(loc->token_pos_ != Scanner::kNoSourcePos);
+  ASSERT(loc->token_pos_ >= 0);
   ASSERT((loc != NULL) && loc->IsResolved());
   ASSERT(!func.HasOptimizedCode());
   Code& code = Code::Handle(func.unoptimized_code());
@@ -2641,7 +2641,7 @@
   if (!frame->IsDebuggable()) {
     return Error::null();
   }
-  if (frame->TokenPos() == Scanner::kNoSourcePos) {
+  if (frame->TokenPos() < 0) {
     return Error::null();
   }
 
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index cd1b8c8..8487801 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -1511,8 +1511,8 @@
 
 
 TEST_CASE(Debug_InterruptIsolate) {
-  Dart_SetIsolateEventHandler(&TestInterruptIsolate);
   sync = new Monitor();
+  Dart_SetIsolateEventHandler(&TestInterruptIsolate);
   EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID);
   Dart_SetPausedEventHandler(InterruptIsolateHandler);
   int result = OSThread::Start("DebugInterruptIsolate", InterruptIsolateRun, 0);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index fc3264f..fed89bb 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -372,6 +372,8 @@
       instr->AsGoto()->adjust_edge_weight(scale_factor);
     }
   }
+
+  RemoveUnreachableExits(callee_graph);
 }
 
 
@@ -395,6 +397,25 @@
 }
 
 
+void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) {
+  const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder();
+  int j = 0;
+  for (int i = 0; i < exits_.length(); ++i) {
+    BlockEntryInstr* block = exits_[i].exit_return->GetBlock();
+    if ((block != NULL) &&
+        (0 <= block->postorder_number()) &&
+        (block->postorder_number() < postorder.length()) &&
+        (postorder[block->postorder_number()] == block)) {
+      if (i != j) {
+        exits_[j] = exits_[i];
+      }
+      j++;
+    }
+  }
+  exits_.TruncateTo(j);
+}
+
+
 void InlineExitCollector::SortExits() {
   // Assign block entries here because we did not necessarily know them when
   // the return exit was added to the array.
@@ -826,17 +847,18 @@
 
 
 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
-                                                Value* value) {
+                                                Value* value,
+                                                intptr_t token_pos) {
   if (local.is_captured()) {
     LocalVariable* tmp_var = EnterTempLocalScope(value);
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
-    Value* context = Bind(BuildCurrentContext());
+    Value* context = Bind(BuildCurrentContext(token_pos));
     while (delta-- > 0) {
       context = Bind(new(Z) LoadFieldInstr(
           context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
-          Scanner::kNoSourcePos));
+          token_pos));
     }
     Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
     StoreInstanceFieldInstr* store =
@@ -844,61 +866,68 @@
                                        context,
                                        tmp_val,
                                        kEmitStoreBarrier,
-                                       Scanner::kNoSourcePos);
+                                       token_pos);
     Do(store);
     return ExitTempLocalScope(tmp_var);
   } else {
-    return new(Z) StoreLocalInstr(local, value);
+    return new(Z) StoreLocalInstr(local, value, token_pos);
   }
 }
 
 
-Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
+Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local,
+                                               intptr_t token_pos) {
   if (local.IsConst()) {
-    return new(Z) ConstantInstr(*local.ConstValue());
+    return new(Z) ConstantInstr(*local.ConstValue(), token_pos);
   } else if (local.is_captured()) {
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
-    Value* context = Bind(BuildCurrentContext());
+    Value* context = Bind(BuildCurrentContext(token_pos));
     while (delta-- > 0) {
       context = Bind(new(Z) LoadFieldInstr(
           context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
-          Scanner::kNoSourcePos));
+          token_pos));
     }
     return new(Z) LoadFieldInstr(context,
-                              Context::variable_offset(local.index()),
-                              local.type(),
-                              Scanner::kNoSourcePos);
+                                 Context::variable_offset(local.index()),
+                                 local.type(),
+                                 token_pos);
   } else {
-    return new(Z) LoadLocalInstr(local);
+    return new(Z) LoadLocalInstr(local, token_pos);
   }
 }
 
 
 // Stores current context into the 'variable'
-void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
-  Value* context = Bind(BuildCurrentContext());
-  Do(BuildStoreLocal(variable, context));
+void EffectGraphVisitor::BuildSaveContext(
+    const LocalVariable& variable,
+    intptr_t token_pos) {
+  Value* context = Bind(BuildCurrentContext(token_pos));
+  Do(BuildStoreLocal(variable, context, token_pos));
 }
 
 
 // Loads context saved in 'context_variable' into the current context.
-void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
-  Value* load_saved_context = Bind(BuildLoadLocal(variable));
-  Do(BuildStoreContext(load_saved_context));
+void EffectGraphVisitor::BuildRestoreContext(
+    const LocalVariable& variable,
+    intptr_t token_pos) {
+  Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos));
+  Do(BuildStoreContext(load_saved_context, token_pos));
 }
 
 
-Definition* EffectGraphVisitor::BuildStoreContext(Value* value) {
+Definition* EffectGraphVisitor::BuildStoreContext(
+    Value* value, intptr_t token_pos) {
   return new(Z) StoreLocalInstr(
-      *owner()->parsed_function().current_context_var(), value);
+      *owner()->parsed_function().current_context_var(), value, token_pos);
 }
 
 
-Definition* EffectGraphVisitor::BuildCurrentContext() {
+Definition* EffectGraphVisitor::BuildCurrentContext(intptr_t token_pos) {
   return new(Z) LoadLocalInstr(
-      *owner()->parsed_function().current_context_var());
+      *owner()->parsed_function().current_context_var(),
+      token_pos);
 }
 
 
@@ -1093,7 +1122,7 @@
   // statements for which there is no associated source position.
   const Function& function = owner()->function();
   if (FLAG_support_debugger &&
-      (node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) {
+      (node->token_pos() >= 0) && !function.is_native()) {
     AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(),
                                               RawPcDescriptors::kRuntimeCall));
   }
@@ -1103,7 +1132,7 @@
   if (node->inlined_finally_list_length() > 0) {
     LocalVariable* temp = owner()->parsed_function().finally_return_temp_var();
     ASSERT(temp != NULL);
-    Do(BuildStoreLocal(*temp, return_value));
+    Do(BuildStoreLocal(*temp, return_value, node->token_pos()));
     for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
       InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)");
       EffectGraphVisitor for_effect(owner());
@@ -1113,7 +1142,7 @@
         return;
       }
     }
-    return_value = Bind(BuildLoadLocal(*temp));
+    return_value = Bind(BuildLoadLocal(*temp, node->token_pos()));
   }
 
   if (Isolate::Current()->flags().type_checks()) {
@@ -1155,12 +1184,12 @@
     ASSERT(rcv_var != NULL && rcv_var->is_captured());
     ZoneGrowableArray<PushArgumentInstr*>* arguments =
         new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
-    Value* rcv_value = Bind(BuildLoadLocal(*rcv_var));
+    Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos()));
     arguments->Add(PushArgument(rcv_value));
     Value* returned_value = Bind(BuildLoadExprTemp());
     arguments->Add(PushArgument(returned_value));
     InstanceCallInstr* call = new(Z) InstanceCallInstr(
-        Scanner::kNoSourcePos,
+        node->token_pos(),
         Symbols::CompleterComplete(),
         Token::kILLEGAL,
         arguments,
@@ -1195,7 +1224,7 @@
 
 // <Expression> ::= Literal { literal: Instance }
 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
-  ReturnDefinition(new(Z) ConstantInstr(node->literal()));
+  ReturnDefinition(new(Z) ConstantInstr(node->literal(), node->token_pos()));
 }
 
 
@@ -2262,7 +2291,7 @@
       Smi::ZoneHandle(Z, Smi::New(jump_count))));
   Do(BuildStoreLocal(*jump_var, jump_val));
   // Save the current context for resuming.
-  BuildSaveContext(*ctx_var);
+  BuildSaveContext(*ctx_var, node->token_pos());
 }
 
 
@@ -2284,7 +2313,7 @@
   char name[64];
   OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
   LocalVariable*  var =
-      new(Z) LocalVariable(0,
+      new(Z) LocalVariable(Scanner::kNoSourcePos,
                            String::ZoneHandle(Z, Symbols::New(name)),
                            *value->Type()->ToAbstractType());
   var->set_index(index);
@@ -2538,8 +2567,9 @@
       }
     } else {
       // Store current context in closure.
-      closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
-      Value* context = Bind(BuildCurrentContext());
+      closure_tmp_val = Bind(
+          new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
+      Value* context = Bind(BuildCurrentContext(node->token_pos()));
       Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
                                         closure_tmp_val,
                                         context,
@@ -2747,9 +2777,9 @@
 
 
 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
-  Value* context = Bind(BuildCurrentContext());
+  Value* context = Bind(BuildCurrentContext(node->token_pos()));
   Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context));
-  Do(BuildStoreContext(clone));
+  Do(BuildStoreContext(clone, node->token_pos()));
 }
 
 
@@ -2778,14 +2808,10 @@
 void EffectGraphVisitor::BuildConstructorCall(
     ConstructorCallNode* node,
     PushArgumentInstr* push_alloc_value) {
-  Value* ctor_arg = Bind(new(Z) ConstantInstr(
-      Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))));
-  PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   arguments->Add(push_alloc_value);
-  arguments->Add(push_ctor_arg);
 
   BuildPushArguments(*node->arguments(), arguments);
   Do(new(Z) StaticCallInstr(node->token_pos(),
@@ -3583,7 +3609,7 @@
 
 
 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
-  Definition* load = BuildLoadLocal(node->local());
+  Definition* load = BuildLoadLocal(node->local(), node->token_pos());
   ReturnDefinition(load);
 }
 
@@ -3601,7 +3627,7 @@
             !node->value()->AsLoadLocalNode()->local().IsInternal()) ||
         node->value()->IsClosureNode()) &&
         !node->local().IsInternal() &&
-        (node->token_pos() != Scanner::kNoSourcePos)) {
+        (node->token_pos() >= 0)) {
       AddInstruction(new(Z) DebugStepCheckInstr(
           node->token_pos(), RawPcDescriptors::kRuntimeCall));
     }
@@ -3617,7 +3643,9 @@
                                        node->local().type(),
                                        node->local().name());
   }
-  Definition* store = BuildStoreLocal(node->local(), store_value);
+  Definition* store = BuildStoreLocal(node->local(),
+                                      store_value,
+                                      node->token_pos());
   ReturnDefinition(store);
 }
 
@@ -3690,22 +3718,26 @@
 
 
 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
+  const intptr_t token_pos = node->token_pos();
   if (node->field().is_const()) {
     ASSERT(node->field().StaticValue() != Object::sentinel().raw());
     ASSERT(node->field().StaticValue() !=
            Object::transition_sentinel().raw());
     Definition* result = new(Z) ConstantInstr(
-        Instance::ZoneHandle(Z, node->field().StaticValue()));
+        Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos);
     return ReturnDefinition(result);
   }
-  Value* field_value = Bind(new(Z) ConstantInstr(node->field()));
-  LoadStaticFieldInstr* load = new(Z) LoadStaticFieldInstr(field_value);
+  Value* field_value = Bind(new(Z) ConstantInstr(node->field(), token_pos));
+  LoadStaticFieldInstr* load =
+      new(Z) LoadStaticFieldInstr(field_value, token_pos);
   ReturnDefinition(load);
 }
 
 
 Definition* EffectGraphVisitor::BuildStoreStaticField(
-  StoreStaticFieldNode* node, bool result_is_needed) {
+    StoreStaticFieldNode* node,
+    bool result_is_needed,
+    intptr_t token_pos) {
   ValueGraphVisitor for_value(owner());
   node->value()->Visit(&for_value);
   Append(for_value);
@@ -3716,7 +3748,7 @@
     store_value = for_value.value();
   }
   StoreStaticFieldInstr* store =
-      new(Z) StoreStaticFieldInstr(node->field(), store_value);
+      new(Z) StoreStaticFieldInstr(node->field(), store_value, token_pos);
 
   if (result_is_needed) {
     Do(store);
@@ -3728,12 +3760,14 @@
 
 
 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
-  ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded));
+  ReturnDefinition(
+      BuildStoreStaticField(node, kResultNotNeeded, node->token_pos()));
 }
 
 
 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
-  ReturnDefinition(BuildStoreStaticField(node, kResultNeeded));
+  ReturnDefinition(
+      BuildStoreStaticField(node, kResultNeeded, node->token_pos()));
 }
 
 
@@ -3909,17 +3943,19 @@
 
 
 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
+  // TODO(johnmccutchan): Pass this in.
+  const intptr_t token_pos = ClassifyingTokenPositions::kContext;
   if (n > 0) {
-    Value* context = Bind(BuildCurrentContext());
+    Value* context = Bind(BuildCurrentContext(token_pos));
     while (n-- > 0) {
       context = Bind(
           new(Z) LoadFieldInstr(context,
                                 Context::parent_offset(),
                                 // Not an instance, no type.
                                 Type::ZoneHandle(Z, Type::null()),
-                                Scanner::kNoSourcePos));
+                                token_pos));
     }
-    Do(BuildStoreContext(context));
+    Do(BuildStoreContext(context, token_pos));
   }
 }
 
@@ -3977,15 +4013,18 @@
         ASSERT(is_top_level_sequence ||
                (nested_block.ContextLevel() ==
                 nested_block.outer()->ContextLevel() + 1));
-        Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
-        Value* parent_context = Bind(BuildCurrentContext());
+        Value* tmp_val = Bind(
+            new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
+        Value* parent_context = Bind(BuildCurrentContext(node->token_pos()));
         Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(),
                                           tmp_val,
                                           parent_context,
                                           kEmitStoreBarrier,
-                                          Scanner::kNoSourcePos));
+                                          node->token_pos()));
       }
-      Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var))));
+      Do(BuildStoreContext(
+          Bind(ExitTempLocalScope(tmp_var)),
+          node->token_pos()));
     }
 
     // If this node_sequence is the body of the function being compiled, copy
@@ -4002,7 +4041,7 @@
           // Create a temporary local describing the original position.
           const String& temp_name = Symbols::TempParam();
           LocalVariable* temp_local = new(Z) LocalVariable(
-              0,  // Token index.
+              Scanner::kNoSourcePos,  // Token index.
               temp_name,
               Object::dynamic_type());  // Type.
           temp_local->set_index(param_frame_index);
@@ -4040,9 +4079,10 @@
       const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
       check_pos = parameter.token_pos();
     }
-    if (check_pos == Scanner::kNoSourcePos) {
+    if (check_pos < 0) {
       // No parameters or synthetic parameters.
       check_pos = node->token_pos();
+      ASSERT(check_pos >= 0);
     }
     AddInstruction(new(Z) DebugStepCheckInstr(check_pos,
                                               RawPcDescriptors::kRuntimeCall));
@@ -4056,7 +4096,7 @@
     if (!function.IsImplicitGetterFunction() &&
         !function.IsImplicitSetterFunction()) {
       CheckStackOverflowInstr* check =
-          new(Z) CheckStackOverflowInstr(function.token_pos(), 0);
+          new(Z) CheckStackOverflowInstr(node->token_pos(), 0);
       // If we are inlining don't actually attach the stack check. We must still
       // create the stack check in order to allocate a deopt id.
       if (!owner()->IsInlining()) {
@@ -4068,12 +4108,11 @@
   if (Isolate::Current()->flags().type_checks() && is_top_level_sequence) {
     const int num_params = function.NumParameters();
     int pos = 0;
-    if (function.IsGenerativeConstructor()) {
-      // Skip type checking of receiver and phase for constructor functions.
-      pos = 2;
-    } else if (function.IsFactory() || function.IsDynamicFunction()) {
+    if (function.IsFactory() ||
+        function.IsDynamicFunction() ||
+        function.IsGenerativeConstructor()) {
       // Skip type checking of type arguments for factory functions.
-      // Skip type checking of receiver for instance functions.
+      // Skip type checking of receiver for instance functions and constructors.
       pos = 1;
     }
     while (pos < num_params) {
@@ -4167,7 +4206,7 @@
 
       // Restore the saved continuation context, i.e. the context that was
       // saved into :await_ctx_var before the closure suspended.
-      for_true.BuildRestoreContext(*old_context);
+      for_true.BuildRestoreContext(*old_context, Scanner::kNoSourcePos);
 
       // Goto saved join.
       for_true.Goto((*owner()->await_joins())[i]);
@@ -4209,7 +4248,7 @@
 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
   InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
   // Restores current context from local variable ':saved_try_context_var'.
-  BuildRestoreContext(node->context_var());
+  BuildRestoreContext(node->context_var(), node->token_pos());
 
   EffectGraphVisitor for_catch(owner());
   node->VisitChildren(&for_catch);
@@ -4219,13 +4258,13 @@
 
 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
   InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)");
-  intptr_t original_handler_index = owner()->try_index();
+  const intptr_t original_handler_index = owner()->try_index();
   const intptr_t try_handler_index = node->try_index();
   ASSERT(try_handler_index != original_handler_index);
   owner()->set_try_index(try_handler_index);
 
   // Preserve current context into local variable ':saved_try_context_var'.
-  BuildSaveContext(node->context_var());
+  BuildSaveContext(node->context_var(), node->token_pos());
 
   EffectGraphVisitor for_try(owner());
   node->try_block()->Visit(&for_try);
@@ -4291,13 +4330,15 @@
   }
 
   if (finally_block != NULL) {
+    ASSERT(node->rethrow_clause() != NULL);
     // Create a handler for the code in the catch block, containing the
     // code in the finally block.
     owner()->set_try_index(original_handler_index);
     EffectGraphVisitor for_finally(owner());
-    for_finally.BuildRestoreContext(catch_block->context_var());
+    for_finally.BuildRestoreContext(catch_block->context_var(),
+                                    finally_block->token_pos());
 
-    finally_block->Visit(&for_finally);
+    node->rethrow_clause()->Visit(&for_finally);
     if (for_finally.is_open()) {
       // Rethrow the exception.  Manually build the graph for rethrow.
       Value* exception = for_finally.Bind(
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 5511db4..94c9444 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -42,6 +42,8 @@
   // Before replacing a call with a graph, the outer environment needs to be
   // attached to each instruction in the callee graph and the caller graph
   // needs to have its block and instruction ID state updated.
+  // Additionally we need to remove all unreachable exits from the list of
+  // collected exits.
   void PrepareGraphs(FlowGraph* callee_graph);
 
   // Inline a graph at a call site.
@@ -78,6 +80,7 @@
 
   static int LowestBlockIdFirst(const Data* a, const Data* b);
   void SortExits();
+  void RemoveUnreachableExits(FlowGraph* callee_graph);
 
   Definition* JoinReturns(BlockEntryInstr** exit_block,
                           Instruction** last_instruction,
@@ -304,8 +307,11 @@
   Definition* BuildStoreExprTemp(Value* value);
   Definition* BuildLoadExprTemp();
 
-  Definition* BuildStoreLocal(const LocalVariable& local, Value* value);
-  Definition* BuildLoadLocal(const LocalVariable& local);
+  Definition* BuildStoreLocal(const LocalVariable& local,
+                              Value* value,
+                              intptr_t token_pos = Scanner::kNoSourcePos);
+  Definition* BuildLoadLocal(const LocalVariable& local,
+                             intptr_t token_pos = Scanner::kNoSourcePos);
   LoadLocalInstr* BuildLoadThisVar(LocalScope* scope);
   LoadFieldInstr* BuildNativeGetter(
       NativeBodyNode* node,
@@ -390,11 +396,13 @@
   void BuildConstructorCall(ConstructorCallNode* node,
                             PushArgumentInstr* alloc_value);
 
-  void BuildSaveContext(const LocalVariable& variable);
-  void BuildRestoreContext(const LocalVariable& variable);
+  void BuildSaveContext(const LocalVariable& variable,
+                        intptr_t token_pos);
+  void BuildRestoreContext(const LocalVariable& variable,
+                           intptr_t token_pos);
 
-  Definition* BuildStoreContext(Value* value);
-  Definition* BuildCurrentContext();
+  Definition* BuildStoreContext(Value* value, intptr_t token_pos);
+  Definition* BuildCurrentContext(intptr_t token_pos);
 
   void BuildThrowNode(ThrowNode* node);
 
@@ -415,7 +423,8 @@
 
   void BuildStaticSetter(StaticSetterNode* node, bool result_is_needed);
   Definition* BuildStoreStaticField(StoreStaticFieldNode* node,
-                                    bool result_is_needed);
+                                    bool result_is_needed,
+                                    intptr_t token_pos);
 
   void BuildClosureCall(ClosureCallNode* node, bool result_needed);
 
diff --git a/runtime/vm/flow_graph_builder_test.cc b/runtime/vm/flow_graph_builder_test.cc
new file mode 100644
index 0000000..91a13b2
--- /dev/null
+++ b/runtime/vm/flow_graph_builder_test.cc
@@ -0,0 +1,663 @@
+// Copyright (c) 2016, 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.
+
+#include "vm/compiler.h"
+#include "vm/dart_api_impl.h"
+#include "vm/dart_entry.h"
+#include "vm/flow_graph_builder.h"
+#include "vm/intermediate_language.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#define DUMP_ASSERT(condition)                                                 \
+  if (!(condition)) {                                                          \
+    dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition);         \
+    THR_Print(">>> BEGIN source position table for `%s`\n", graph_name_);      \
+    Dump();                                                                    \
+    THR_Print("<<< END source position table for `%s`\n", graph_name_);        \
+    OS::Abort();                                                               \
+  }
+
+class SourcePositionTest : public ValueObject {
+ public:
+  SourcePositionTest(Thread* thread,
+                     const char* script)
+      : thread_(thread),
+        isolate_(thread->isolate()),
+        script_(script),
+        root_lib_(Library::Handle()),
+        root_script_(Script::Handle()),
+        graph_(NULL),
+        blocks_(NULL) {
+    EXPECT(thread_ != NULL);
+    EXPECT(isolate_ != NULL);
+    EXPECT(script_ != NULL);
+    Dart_Handle lib = TestCase::LoadTestScript(script, NULL);
+    EXPECT_VALID(lib);
+    root_lib_ ^= Api::UnwrapHandle(lib);
+    EXPECT(!root_lib_.IsNull());
+    root_script_ ^= root_lib_.LookupScript(
+        String::Handle(String::New(USER_TEST_URI)));
+    EXPECT(!root_script_.IsNull());
+  }
+
+  void BuildGraphFor(const char* function_name) {
+    graph_ = NULL;
+    blocks_ = NULL;
+    graph_name_ = NULL;
+
+    // Only support unoptimized code for now.
+    const bool optimized = false;
+
+    const Function& function =
+        Function::Handle(GetFunction(root_lib_, function_name));
+    ZoneGrowableArray<const ICData*>* ic_data_array =
+        new ZoneGrowableArray<const ICData*>();
+    ParsedFunction* parsed_function = new ParsedFunction(
+        thread_, Function::ZoneHandle(function.raw()));
+    Parser::ParseFunction(parsed_function);
+    parsed_function->AllocateVariables();
+    FlowGraphBuilder builder(
+        *parsed_function,
+        *ic_data_array,
+        NULL,
+        Compiler::kNoOSRDeoptId);
+    graph_ = builder.BuildGraph();
+    EXPECT(graph_ != NULL);
+    blocks_ = graph_->CodegenBlockOrder(optimized);
+    EXPECT(blocks_ != NULL);
+    graph_name_ = function_name;
+    EXPECT(graph_name_ != NULL);
+  }
+
+  // Expect to find an instance call at |line| and |column|.
+  void InstanceCallAt(intptr_t line,
+                      intptr_t column = -1,
+                      Token::Kind kind = Token::kNumTokens) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      EXPECT(instr != NULL);
+      if (instr->IsInstanceCall()) {
+        if (kind != Token::kNumTokens) {
+          if (instr->AsInstanceCall()->token_kind() == kind) {
+            count++;
+          }
+        } else {
+          count++;
+        }
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
+  // Expect to find at least one static call at |line| and |column|. The
+  // static call will have |needle| in its |ToCString| representation.
+  void StaticCallAt(const char* needle,
+                    intptr_t line,
+                    intptr_t column = -1) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      EXPECT(instr != NULL);
+      if (instr->IsStaticCall()) {
+        const char* haystack = instr->ToCString();
+        if (strstr(haystack, needle) != NULL) {
+          count++;
+        }
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
+  // Expect that at least one of the instructions found at |line| and |column|
+  // contain |needle| in their |ToCString| representation.
+  void FuzzyInstructionMatchAt(const char* needle,
+                               intptr_t line,
+                               intptr_t column = -1) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      const char* haystack = instr->ToCString();
+      if (strstr(haystack, needle) != NULL) {
+        count++;
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
+  // Utility to dump the instructions with token positions or line numbers.
+  void Dump() {
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      THR_Print("B%" Pd ":\n", entry->block_id());
+      DumpInstruction(entry);
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        DumpInstruction(it.Current());
+      }
+    }
+  }
+
+ private:
+  void DumpInstruction(Instruction* instr) {
+    const intptr_t token_pos = instr->token_pos();
+    if (token_pos < 0) {
+      const char* token_pos_string =
+          ClassifyingTokenPositions::ToCString(token_pos);
+      THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString());
+      return;
+    }
+    intptr_t token_line = -1;
+    intptr_t token_column = -1;
+    root_script_.GetTokenLocation(token_pos,
+                                  &token_line,
+                                  &token_column,
+                                  NULL);
+    THR_Print("       %02d:%02d -- %s\n",
+              static_cast<int>(token_line),
+              static_cast<int>(token_column),
+              instr->ToCString());
+  }
+
+  Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    if (instructions->length() == 0) {
+      return NULL;
+    }
+    return instructions->At(0);
+  }
+
+  ZoneGrowableArray<Instruction*>* FindInstructionsAt(
+      intptr_t line, intptr_t column) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        new ZoneGrowableArray<Instruction*>();
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        Instruction* instr = it.Current();
+        intptr_t token_pos = instr->token_pos();
+        if (token_pos < 0) {
+          continue;
+        }
+        intptr_t token_line = -1;
+        intptr_t token_column = -1;
+        root_script_.GetTokenLocation(token_pos,
+                                      &token_line,
+                                      &token_column,
+                                      NULL);
+        if (token_line == line) {
+          if ((column < 0) || (column == token_column)) {
+            instructions->Add(instr);
+          }
+        }
+      }
+    }
+    return instructions;
+  }
+
+  ZoneGrowableArray<Instruction*>* FindInstructionsAt(intptr_t token_pos) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        new ZoneGrowableArray<Instruction*>();
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        Instruction* instr = it.Current();
+        if (instr->token_pos() == token_pos) {
+          instructions->Add(instr);
+        }
+      }
+    }
+    return instructions;
+  }
+
+  RawFunction* GetFunction(const Library& lib, const char* name) {
+    const Function& result = Function::Handle(lib.LookupFunctionAllowPrivate(
+        String::Handle(String::New(name))));
+    EXPECT(!result.IsNull());
+    return result.raw();
+  }
+
+  RawFunction* GetFunction(const Class& cls, const char* name) {
+    const Function& result = Function::Handle(cls.LookupFunctionAllowPrivate(
+        String::Handle(String::New(name))));
+    EXPECT(!result.IsNull());
+    return result.raw();
+  }
+
+  RawClass* GetClass(const Library& lib, const char* name) {
+    const Class& cls = Class::Handle(
+        lib.LookupClass(String::Handle(Symbols::New(name))));
+    EXPECT(!cls.IsNull());  // No ambiguity error expected.
+    return cls.raw();
+  }
+
+  Thread* thread_;
+  Isolate* isolate_;
+  const char* script_;
+  Library& root_lib_;
+  Script& root_script_;
+  const char* graph_name_;
+  FlowGraph* graph_;
+  GrowableArray<BlockEntryInstr*>* blocks_;
+};
+
+
+TEST_CASE(SourcePosition_InstanceCalls) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  var z = x + y;\n"
+      "  return z;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.InstanceCallAt(4, 13, Token::kADD);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3);
+  spt.FuzzyInstructionMatchAt("Return", 5, 3);
+}
+
+
+TEST_CASE(SourcePosition_If) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  if (x != 0) {\n"
+      "    return x;\n"
+      "  }\n"
+      "  return y;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7);
+  spt.InstanceCallAt(4, 9, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5);
+  spt.FuzzyInstructionMatchAt("Return", 5, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3);
+  spt.FuzzyInstructionMatchAt("Return", 7, 3);
+}
+
+
+TEST_CASE(SourcePosition_ForLoop) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  for (var i = 0; i < 10; i++) {\n"
+      "    x += i;\n"
+      "  }\n"
+      "  return x;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("StoreLocal", 4, 14);
+  spt.FuzzyInstructionMatchAt("LoadLocal", 4, 19);
+  spt.InstanceCallAt(4, 21, Token::kLT);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 21);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 5);
+  spt.FuzzyInstructionMatchAt("StoreStaticField", 5, 5);
+  spt.InstanceCallAt(5, 7, Token::kADD);
+  spt.FuzzyInstructionMatchAt("LoadLocal", 5, 10);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3);
+  spt.FuzzyInstructionMatchAt("Return", 7, 3);
+}
+
+
+TEST_CASE(SourcePosition_While) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  while (x < 10) {\n"
+      "    if (y == 5) {\n"
+      "      return y;\n"
+      "    }\n"
+      "    x++;\n"
+      "  }\n"
+      "  return x;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant", 4, 10);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 10);
+  spt.InstanceCallAt(4, 12, Token::kLT);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 12);
+
+  spt.FuzzyInstructionMatchAt("Constant", 5, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9);
+  spt.InstanceCallAt(5, 11, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11);
+
+  spt.FuzzyInstructionMatchAt("Constant", 6, 14);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 14);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 7);
+  spt.FuzzyInstructionMatchAt("Return", 6, 7);
+
+  spt.FuzzyInstructionMatchAt("Constant", 8, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 8, 5);
+  spt.FuzzyInstructionMatchAt("Constant(#1)", 8, 6);
+  spt.InstanceCallAt(8, 6, Token::kADD);
+  spt.FuzzyInstructionMatchAt("StoreStaticField", 8, 5);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3);
+  spt.FuzzyInstructionMatchAt("Return", 10, 3);
+}
+
+
+TEST_CASE(SourcePosition_WhileContinueBreak) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  while (x < 10) {\n"
+      "    if (y == 5) {\n"
+      "      continue;\n"
+      "    }\n"
+      "    break;\n"
+      "  }\n"
+      "  return x;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant(#Field", 4, 10);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 10);
+  spt.FuzzyInstructionMatchAt("Constant(#10", 4, 14);
+  spt.InstanceCallAt(4, 12, Token::kLT);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 12);
+
+  spt.FuzzyInstructionMatchAt("Constant(#Field", 5, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9);
+  spt.FuzzyInstructionMatchAt("Constant(#5", 5, 14);
+  spt.InstanceCallAt(5, 11, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3);
+  spt.FuzzyInstructionMatchAt("Return", 10, 3);
+}
+
+
+TEST_CASE(SourcePosition_LoadIndexed) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var z = new List(3);\n"
+      "main() {\n"
+      "  z[0];\n"
+      "  var y = z[0] + z[1] + z[2];\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.StaticCallAt("get:z", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 4, 5);
+  spt.InstanceCallAt(4, 4, Token::kINDEX);
+
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 5, 13);
+  spt.InstanceCallAt(5, 12, Token::kINDEX);
+  spt.FuzzyInstructionMatchAt("Constant(#1)", 5, 20);
+  spt.InstanceCallAt(5, 19, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 16, Token::kADD);
+
+  spt.StaticCallAt("get:z", 5, 25);
+  spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 27);
+  spt.InstanceCallAt(5, 26, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 23, Token::kADD);
+
+  spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1);
+  spt.FuzzyInstructionMatchAt("Return", 6, 1);
+}
+
+
+TEST_CASE(SourcePosition_StoreIndexed) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var z = new List(4);\n"
+      "main() {\n"
+      "  z[0];\n"
+      "  z[3] = z[0] + z[1] + z[2];\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.StaticCallAt("get:z", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 4, 5);
+  spt.InstanceCallAt(4, 4, Token::kINDEX);
+
+  spt.FuzzyInstructionMatchAt("Constant(#3)", 5, 5);
+
+  spt.StaticCallAt("get:z", 5, 10);
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 5, 12);
+  spt.InstanceCallAt(5, 11, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 15, Token::kADD);
+
+  spt.StaticCallAt("get:z", 5, 17);
+  spt.FuzzyInstructionMatchAt("Constant(#1)", 5, 19);
+  spt.InstanceCallAt(5, 18, Token::kINDEX);
+
+  spt.StaticCallAt("get:z", 5, 24);
+  spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 26);
+  spt.InstanceCallAt(5, 25, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 4, Token::kASSIGN_INDEX);
+
+  spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1);
+  spt.FuzzyInstructionMatchAt("Return", 6, 1);
+}
+
+
+TEST_CASE(SourcePosition_BitwiseOperations) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 1;\n"
+      "main() {\n"
+      "  var z;\n"
+      "  z = x & y;\n"
+      "  z = x | y;\n"
+      "  z = x ^ y;\n"
+      "  z = ~z;\n"
+      "  return z;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 4, 7);
+  spt.FuzzyInstructionMatchAt("Constant(#null", 4, 7);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 4, 7);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 7);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 11);
+  spt.InstanceCallAt(5, 9, Token::kBIT_AND);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 5, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 7);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 11);
+  spt.InstanceCallAt(6, 9, Token::kBIT_OR);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 7);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 11);
+  spt.InstanceCallAt(7, 9, Token::kBIT_XOR);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 7, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(z", 8, 8);
+  spt.InstanceCallAt(8, 7, Token::kBIT_NOT);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 8, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(z", 9, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3);
+  spt.FuzzyInstructionMatchAt("Return", 9, 3);
+}
+
+
+TEST_CASE(SourcePosition_IfElse) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  if (x != 0) {\n"
+      "    return x;\n"
+      "  } else {\n"
+      "    return y;\n"
+      "  }\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7);
+  spt.InstanceCallAt(4, 9, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5);
+  spt.FuzzyInstructionMatchAt("Return", 5, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 12);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 5);
+  spt.FuzzyInstructionMatchAt("Return", 7, 5);
+}
+
+
+TEST_CASE(SourcePosition_Switch) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  switch (x) {\n"
+      "    case 1: return 3;\n"
+      "    case 2: return 4;\n"
+      "    default: return 5;\n"
+      "  }\n"
+      "}\n";
+
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("Constant(#Field", 4, 11);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 11);
+  spt.FuzzyInstructionMatchAt("StoreLocal(:switch_expr", 4, 11);
+
+  spt.FuzzyInstructionMatchAt("Constant(#1", 5, 10);
+  spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 5, 5);   // 'c'
+  spt.InstanceCallAt(5, 10, Token::kEQ);                         // '1'
+
+  spt.FuzzyInstructionMatchAt("Constant(#3", 5, 20);             // '3'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 13);
+  spt.FuzzyInstructionMatchAt("Return", 5, 13);
+
+  spt.FuzzyInstructionMatchAt("Constant(#2", 6, 10);
+  spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 6, 5);   // 'c'
+  spt.InstanceCallAt(6, 10, Token::kEQ);                         // '2'
+
+  spt.FuzzyInstructionMatchAt("Constant(#4", 6, 20);             // '4'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 13);
+  spt.FuzzyInstructionMatchAt("Return", 6, 13);
+
+  spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21);             // '5'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14);
+  spt.FuzzyInstructionMatchAt("Return", 7, 14);
+}
+
+
+TEST_CASE(SourcePosition_TryCatchFinally) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  try {\n"
+      "    throw 'A';\n"
+      "  } catch (e) {\n"
+      "    print(e);\n"
+      "    return 77;\n"
+      "  } finally {\n"
+      "    return 99;\n"
+      "  }\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(:current_context", 4, 3);     // 't'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:saved_try_context", 4, 3);
+
+  spt.FuzzyInstructionMatchAt("Constant(#A", 5, 11);                   // 'A'
+  spt.FuzzyInstructionMatchAt("Throw", 5, 5);                          // 't'
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 6, 5);   // 'c'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 6, 5);    // 'c'
+  spt.FuzzyInstructionMatchAt("LoadLocal(:exception_var", 6, 5);       // 'c'
+  spt.FuzzyInstructionMatchAt("StoreLocal(e", 6, 5);                   // 'c'
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(e", 7, 11);                   // 'e'
+
+  spt.FuzzyInstructionMatchAt("StaticCall", 7, 5);                     // 'p'
+
+  spt.FuzzyInstructionMatchAt("Constant(#77", 8, 12);                  // '7'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:finally_ret_val", 8, 5);    // 'r'
+
+  spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12);                 // '9'
+  spt.FuzzyInstructionMatchAt("Return", 10, 5);                        // 'r'
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 9, 13);  // '{'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 9, 13);   // '{'
+
+  spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12);                 // '9'
+  spt.FuzzyInstructionMatchAt("Return", 10, 5);                        // 'r'
+}
+
+}  // namespace dart
+
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index da0639c..1f02942 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -84,6 +84,8 @@
 DECLARE_FLAG(int, inline_getters_setters_smaller_than);
 DECLARE_FLAG(int, inlining_depth_threshold);
 DECLARE_FLAG(int, inlining_caller_size_threshold);
+DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold);
+DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
 
 bool FLAG_precompilation = false;
 static void PrecompilationModeHandler(bool value) {
@@ -135,6 +137,9 @@
     FLAG_inlining_depth_threshold = 2;
     FLAG_inlining_caller_size_threshold = 1000;
 
+    FLAG_inlining_constant_arguments_max_size_threshold = 100;
+    FLAG_inlining_constant_arguments_min_size_threshold = 30;
+
     // Background compilation relies on two-stage compilation pipeline,
     // while precompilation has only one.
     FLAG_background_compilation = false;
@@ -273,7 +278,7 @@
                             isolate()->GetCompilerStream(),
                             "InitCompiler");
   pc_descriptors_list_ = new(zone()) DescriptorList(64);
-  exception_handlers_list_ = new(zone())ExceptionHandlerList();
+  exception_handlers_list_ = new(zone()) ExceptionHandlerList();
   block_info_.Clear();
   // Conservative detection of leaf routines used to remove the stack check
   // on function entry.
@@ -444,7 +449,7 @@
 
 
 void FlowGraphCompiler::EmitSourceLine(Instruction* instr) {
-  if ((instr->token_pos() == Scanner::kNoSourcePos) || (instr->env() == NULL)) {
+  if ((instr->token_pos() < 0) || (instr->env() == NULL)) {
     return;
   }
   const Script& script =
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 0254855..c1eb50c 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -674,7 +674,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1408,7 +1408,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1437,7 +1437,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index d8283b1..f21941f 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -666,7 +666,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1389,7 +1389,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1418,7 +1418,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 53a26cc..e3b0fcf 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -685,7 +685,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1369,7 +1369,7 @@
     } else {
       __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1396,7 +1396,7 @@
     } else {
       __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 55a3dfc..83919f5 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -668,7 +668,7 @@
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
   __ Comment("AssertAssignable");
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1420,7 +1420,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1454,7 +1454,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index fc3d951..4a7c7ab 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -677,7 +677,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1410,7 +1410,7 @@
     } else {
       __ CallPatchable(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1437,7 +1437,7 @@
     } else {
       __ CallPatchable(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index f10e60c..c36bf53 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -225,6 +225,14 @@
       // finalized yet.
       return false;
     }
+    // Do not run the optimization below if in background compilation since
+    // resolution of method extractor functions may create new signature
+    // classes.
+    // TODO(regis): Remove test for background compilation once signature
+    // classes are not generated any longer.
+    if (!thread()->IsMutatorThread()) {
+      return false;
+    }
     const Array& args_desc_array = Array::Handle(Z,
         ArgumentsDescriptor::New(call->ArgumentCount(),
                                  call->argument_names()));
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 3c3725c..7ea528a 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -695,7 +695,7 @@
   // verifying the run time type of the passed-in parameter and this check would
   // always be wrongly eliminated.
   // However there are parameters that are known to match their declared type:
-  // for example receiver and construction phase.
+  // for example receiver.
   GraphEntryInstr* graph_entry = block_->AsGraphEntry();
   // Parameters at catch blocks and OSR entries have type dynamic.
   //
@@ -727,11 +727,6 @@
   LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
   const AbstractType& type = scope->VariableAt(index())->type();
 
-  // Parameter is the constructor phase.
-  if ((index() == 1) && function.IsGenerativeConstructor()) {
-    return CompileType::FromAbstractType(type, CompileType::kNonNullable);
-  }
-
   // Parameter is the receiver.
   if ((index() == 0) &&
       (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 71109ee..10586bd 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -51,7 +51,8 @@
       new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset),
       old_space_(this, max_old_gen_words, max_external_words),
       read_only_(false),
-      gc_in_progress_(false),
+      gc_new_space_in_progress_(false),
+      gc_old_space_in_progress_(false),
       pretenure_policy_(0) {
   for (int sel = 0;
        sel < kNumWeakSelectors;
@@ -79,6 +80,9 @@
   isolate()->AssertCurrentThreadIsMutator();
   uword addr = new_space_.TryAllocate(size);
   if (addr == 0) {
+    // This call to CollectGarbage might end up "reusing" a collection spawned
+    // from a different thread and will be racing to allocate the requested
+    // memory with other threads being released after the collection.
     CollectGarbage(kNew);
     addr = new_space_.TryAllocate(size);
     if (addr == 0) {
@@ -108,35 +112,38 @@
   if (addr != 0) {
     return addr;
   }
-  // All GC tasks finished without allocating successfully. Run a full GC.
-  CollectAllGarbage();
-  addr = old_space_.TryAllocate(size, type);
-  if (addr != 0) {
-    return addr;
-  }
-  // Wait for all of the concurrent tasks to finish before giving up.
-  {
-    MonitorLocker ml(old_space_.tasks_lock());
+  Thread* thread = Thread::Current();
+  if (thread->CanCollectGarbage()) {
+    // All GC tasks finished without allocating successfully. Run a full GC.
+    CollectAllGarbage();
     addr = old_space_.TryAllocate(size, type);
-    while ((addr == 0) && (old_space_.tasks() > 0)) {
-      ml.Wait();
-      addr = old_space_.TryAllocate(size, type);
+    if (addr != 0) {
+      return addr;
     }
-  }
-  if (addr != 0) {
-    return addr;
-  }
-  // Force growth before attempting a synchronous GC.
-  addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
-  if (addr != 0) {
-    return addr;
-  }
-  // Before throwing an out-of-memory error try a synchronous GC.
-  CollectAllGarbage();
-  {
-    MonitorLocker ml(old_space_.tasks_lock());
-    while (old_space_.tasks() > 0) {
-      ml.Wait();
+    // Wait for all of the concurrent tasks to finish before giving up.
+    {
+      MonitorLocker ml(old_space_.tasks_lock());
+      addr = old_space_.TryAllocate(size, type);
+      while ((addr == 0) && (old_space_.tasks() > 0)) {
+        ml.Wait();
+        addr = old_space_.TryAllocate(size, type);
+      }
+    }
+    if (addr != 0) {
+      return addr;
+    }
+    // Force growth before attempting another synchronous GC.
+    addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
+    if (addr != 0) {
+      return addr;
+    }
+    // Before throwing an out-of-memory error try a synchronous GC.
+    CollectAllGarbage();
+    {
+      MonitorLocker ml(old_space_.tasks_lock());
+      while (old_space_.tasks() > 0) {
+        ml.Wait();
+      }
     }
   }
   addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
@@ -307,66 +314,51 @@
 }
 
 
-bool Heap::gc_in_progress() {
-  MutexLocker ml(&gc_in_progress_mutex_);
-  return gc_in_progress_;
-}
-
-
-void Heap::BeginGC() {
-  MutexLocker ml(&gc_in_progress_mutex_);
-  ASSERT(!gc_in_progress_);
-  gc_in_progress_ = true;
-}
-
-
-void Heap::EndGC() {
-  MutexLocker ml(&gc_in_progress_mutex_);
-  ASSERT(gc_in_progress_);
-  gc_in_progress_ = false;
-}
-
-
-void Heap::CollectGarbage(Space space,
-                          ApiCallbacks api_callbacks,
-                          GCReason reason) {
-  Thread* thread = Thread::Current();
-  bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
-  switch (space) {
-    case kNew: {
-      RecordBeforeGC(kNew, reason);
-      VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
-      TimelineDurationScope tds(thread,
-                                isolate()->GetGCStream(),
-                                "CollectNewGeneration");
-      UpdateClassHeapStatsBeforeGC(kNew);
-      new_space_.Scavenge(invoke_api_callbacks);
-      isolate()->class_table()->UpdatePromoted();
-      UpdatePretenurePolicy();
-      RecordAfterGC();
-      PrintStats();
-      if (old_space_.NeedsGarbageCollection()) {
-        // Old collections should call the API callbacks.
-        CollectGarbage(kOld, kInvokeApiCallbacks, kPromotion);
-      }
-      break;
-    }
-    case kOld:
-    case kCode: {
-      RecordBeforeGC(kOld, reason);
-      VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
-      TimelineDurationScope tds(thread,
-                                isolate()->GetGCStream(),
-                                "CollectOldGeneration");
-      UpdateClassHeapStatsBeforeGC(kOld);
-      old_space_.MarkSweep(invoke_api_callbacks);
-      RecordAfterGC();
-      PrintStats();
-      break;
-    }
-    default:
-      UNREACHABLE();
+bool Heap::BeginNewSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  bool start_gc_on_thread = true;
+  while (gc_new_space_in_progress_ ||
+         gc_old_space_in_progress_) {
+    start_gc_on_thread = !gc_new_space_in_progress_;
+    ml.Wait();
   }
+  if (start_gc_on_thread) {
+    gc_new_space_in_progress_ = true;
+    return true;
+  }
+  return false;
+}
+
+
+void Heap::EndNewSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  ASSERT(gc_new_space_in_progress_);
+  gc_new_space_in_progress_ = false;
+  ml.NotifyAll();
+}
+
+
+bool Heap::BeginOldSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  bool start_gc_on_thread = true;
+  while (gc_new_space_in_progress_ ||
+         gc_old_space_in_progress_) {
+    start_gc_on_thread = !gc_old_space_in_progress_;
+    ml.Wait();
+  }
+  if (start_gc_on_thread) {
+    gc_old_space_in_progress_ = true;
+    return true;
+  }
+  return false;
+}
+
+
+void Heap::EndOldSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  ASSERT(gc_old_space_in_progress_);
+  gc_old_space_in_progress_ = false;
+  ml.NotifyAll();
 }
 
 
@@ -380,42 +372,85 @@
 }
 
 
+void Heap::CollectNewSpaceGarbage(Thread* thread,
+                                  ApiCallbacks api_callbacks,
+                                  GCReason reason) {
+  if (BeginNewSpaceGC()) {
+    bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
+    RecordBeforeGC(kNew, reason);
+    VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
+    TimelineDurationScope tds(thread,
+                              isolate()->GetGCStream(),
+                              "CollectNewGeneration");
+    UpdateClassHeapStatsBeforeGC(kNew);
+    new_space_.Scavenge(invoke_api_callbacks);
+    isolate()->class_table()->UpdatePromoted();
+    UpdatePretenurePolicy();
+    RecordAfterGC(kNew);
+    PrintStats();
+    EndNewSpaceGC();
+    if (old_space_.NeedsGarbageCollection()) {
+      // Old collections should call the API callbacks.
+      CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kPromotion);
+    }
+  }
+}
+
+
+void Heap::CollectOldSpaceGarbage(Thread* thread,
+                                  ApiCallbacks api_callbacks,
+                                  GCReason reason) {
+  if (BeginOldSpaceGC()) {
+    bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
+    RecordBeforeGC(kOld, reason);
+    VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
+    TimelineDurationScope tds(thread,
+                              isolate()->GetGCStream(),
+                              "CollectOldGeneration");
+    UpdateClassHeapStatsBeforeGC(kOld);
+    old_space_.MarkSweep(invoke_api_callbacks);
+    RecordAfterGC(kOld);
+    PrintStats();
+    EndOldSpaceGC();
+  }
+}
+
+
+void Heap::CollectGarbage(Space space,
+                          ApiCallbacks api_callbacks,
+                          GCReason reason) {
+  Thread* thread = Thread::Current();
+  switch (space) {
+    case kNew: {
+      CollectNewSpaceGarbage(thread, api_callbacks, reason);
+      break;
+    }
+    case kOld:
+    case kCode: {
+      CollectOldSpaceGarbage(thread, api_callbacks, reason);
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
+}
+
+
 void Heap::CollectGarbage(Space space) {
+  Thread* thread = Thread::Current();
   if (space == kOld) {
-    CollectGarbage(space, kInvokeApiCallbacks, kOldSpace);
+    CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kOldSpace);
   } else {
     ASSERT(space == kNew);
-    CollectGarbage(space, kInvokeApiCallbacks, kNewSpace);
+    CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kNewSpace);
   }
 }
 
 
 void Heap::CollectAllGarbage() {
   Thread* thread = Thread::Current();
-  {
-    RecordBeforeGC(kNew, kFull);
-    VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
-    TimelineDurationScope tds(thread,
-                              isolate()->GetGCStream(),
-                              "CollectNewGeneration");
-    UpdateClassHeapStatsBeforeGC(kNew);
-    new_space_.Scavenge(kInvokeApiCallbacks);
-    isolate()->class_table()->UpdatePromoted();
-    UpdatePretenurePolicy();
-    RecordAfterGC();
-    PrintStats();
-  }
-  {
-    RecordBeforeGC(kOld, kFull);
-    VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
-    TimelineDurationScope tds(thread,
-                              isolate()->GetGCStream(),
-                              "CollectOldGeneration");
-    UpdateClassHeapStatsBeforeGC(kOld);
-    old_space_.MarkSweep(kInvokeApiCallbacks);
-    RecordAfterGC();
-    PrintStats();
-  }
+  CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kFull);
+  CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kFull);
 }
 
 
@@ -694,7 +729,8 @@
 
 
 void Heap::RecordBeforeGC(Space space, GCReason reason) {
-  BeginGC();
+  ASSERT((space == kNew && gc_new_space_in_progress_) ||
+         (space == kOld && gc_old_space_in_progress_));
   stats_.num_++;
   stats_.space_ = space;
   stats_.reason_ = reason;
@@ -712,7 +748,7 @@
 }
 
 
-void Heap::RecordAfterGC() {
+void Heap::RecordAfterGC(Space space) {
   stats_.after_.micros_ = OS::GetCurrentTimeMicros();
   int64_t delta = stats_.after_.micros_ - stats_.before_.micros_;
   if (stats_.space_ == kNew) {
@@ -724,7 +760,8 @@
   }
   stats_.after_.new_ = new_space_.GetCurrentUsage();
   stats_.after_.old_ = old_space_.GetCurrentUsage();
-  EndGC();
+  ASSERT((space == kNew && gc_new_space_in_progress_) ||
+         (space == kOld && gc_old_space_in_progress_));
   if (Service::gc_stream.enabled()) {
     ServiceEvent event(Isolate::Current(), ServiceEvent::kGC);
     event.set_gc_stats(&stats_);
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 2ef3e3c..4a8ae93 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -125,6 +125,9 @@
   void CollectGarbage(Space space);
   void CollectGarbage(Space space, ApiCallbacks api_callbacks, GCReason reason);
   void CollectAllGarbage();
+  bool NeedsGarbageCollection() const {
+    return old_space_.NeedsGarbageCollection();
+  }
 
   // Enables growth control on the page space heaps.  This should be
   // called before any user code is executed.
@@ -231,8 +234,6 @@
     stats_.data_[id] = value;
   }
 
-  bool gc_in_progress();
-
   void UpdateGlobalMaxUsed();
 
   static bool IsAllocatableInNewSpace(intptr_t size) {
@@ -308,16 +309,24 @@
   // ensure thread-safety.
   bool VerifyGC(MarkExpectation mark_expectation = kForbidMarked) const;
 
+  // Helper functions for garbage collection.
+  void CollectNewSpaceGarbage(
+      Thread* thread, ApiCallbacks api_callbacks, GCReason reason);
+  void CollectOldSpaceGarbage(
+      Thread* thread, ApiCallbacks api_callbacks, GCReason reason);
+
   // GC stats collection.
   void RecordBeforeGC(Space space, GCReason reason);
-  void RecordAfterGC();
+  void RecordAfterGC(Space space);
   void PrintStats();
   void UpdateClassHeapStatsBeforeGC(Heap::Space space);
   void UpdatePretenurePolicy();
 
-  // Updates gc_in_progress.
-  void BeginGC();
-  void EndGC();
+  // Updates gc in progress flags.
+  bool BeginNewSpaceGC();
+  void EndNewSpaceGC();
+  bool BeginOldSpaceGC();
+  void EndOldSpaceGC();
 
   // If this heap is non-empty, updates start and end to the smallest range that
   // contains both the original [start, end) and the [lowest, highest) addresses
@@ -340,8 +349,9 @@
   bool read_only_;
 
   // GC on the heap is in progress.
-  Mutex gc_in_progress_mutex_;
-  bool gc_in_progress_;
+  Monitor gc_in_progress_monitor_;
+  bool gc_new_space_in_progress_;
+  bool gc_old_space_in_progress_;
 
   int pretenure_policy_;
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index c73a48f..15635bc 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -420,7 +420,9 @@
 }
 
 
-ConstantInstr::ConstantInstr(const Object& value) : value_(value) {
+ConstantInstr::ConstantInstr(const Object& value, intptr_t token_pos)
+    : value_(value),
+      token_pos_(token_pos) {
   // Check that the value is not an incorrect Integer representation.
   ASSERT(!value.IsBigint() || !Bigint::Cast(value).FitsIntoSmi());
   ASSERT(!value.IsBigint() || !Bigint::Cast(value).FitsIntoInt64());
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 76840bb..876a015 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -38,6 +38,47 @@
 class RangeBoundary;
 class UnboxIntegerInstr;
 
+// These token positions are used to classify instructions that can't be
+// directly tied to an actual source position.
+#define CLASSIFYING_TOKEN_POSITIONS(V)                                         \
+    V(Private, -2)                                                             \
+    V(Box, -3)                                                                 \
+    V(ParallelMove, -4)                                                        \
+    V(TempMove, -5)                                                            \
+    V(Constant, -6)                                                            \
+    V(PushArgument, -7)                                                        \
+    V(ControlFlow, -8)                                                         \
+    V(Context, -9)
+
+// COMPILE_ASSERT that all CLASSIFYING_TOKEN_POSITIONS are less than
+// Scanner::kNoSourcePos.
+#define SANITY_CHECK_VALUES(name, value)                                       \
+  COMPILE_ASSERT(value < Scanner::kNoSourcePos);
+  CLASSIFYING_TOKEN_POSITIONS(SANITY_CHECK_VALUES);
+#undef SANITY_CHECK_VALUES
+
+class ClassifyingTokenPositions : public AllStatic {
+ public:
+#define DEFINE_VALUES(name, value)                                             \
+  static const intptr_t k##name = value;
+  CLASSIFYING_TOKEN_POSITIONS(DEFINE_VALUES);
+#undef DEFINE_VALUES
+
+  static const char* ToCString(intptr_t token_pos) {
+    ASSERT(token_pos < 0);
+    switch (token_pos) {
+      case Scanner::kNoSourcePos: return "NoSource";
+#define DEFINE_CASE(name, value)                                               \
+      case value: return #name;
+      CLASSIFYING_TOKEN_POSITIONS(DEFINE_CASE);
+#undef DEFINE_CASE
+      default:
+        UNIMPLEMENTED();
+        return NULL;
+    }
+  }
+};
+
 // CompileType describes type of the value produced by the definition.
 //
 // It captures the following properties:
@@ -1053,6 +1094,10 @@
 
   virtual void PrintTo(BufferFormatter* f) const;
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kParallelMove;
+  }
+
  private:
   GrowableArray<MoveOperands*> moves_;   // Elements cannot be null.
 
@@ -1185,6 +1230,10 @@
     return this;
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kControlFlow;
+  }
+
   // Helper to mutate the graph during inlining. This block should be
   // replaced with new_block as a predecessor of all of this block's
   // successors.
@@ -2034,6 +2083,10 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kPushArgument;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr);
 };
@@ -2208,6 +2261,10 @@
 
   virtual void PrintTo(BufferFormatter* f) const;
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kControlFlow;
+  }
+
  private:
   BlockEntryInstr* block_;
   JoinEntryInstr* successor_;
@@ -2541,7 +2598,8 @@
 
 class ConstantInstr : public TemplateDefinition<0, NoThrow, Pure> {
  public:
-  explicit ConstantInstr(const Object& value);
+  ConstantInstr(const Object& value,
+                intptr_t token_pos = ClassifyingTokenPositions::kConstant);
 
   DECLARE_INSTRUCTION(Constant)
   virtual CompileType ComputeType() const;
@@ -2558,8 +2616,11 @@
 
   virtual bool AttributesEqual(Instruction* other) const;
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   const Object& value_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
 };
@@ -3249,8 +3310,9 @@
 
 class LoadLocalInstr : public TemplateDefinition<0, NoThrow> {
  public:
-  explicit LoadLocalInstr(const LocalVariable& local)
-      : local_(local), is_last_(false) { }
+  LoadLocalInstr(const LocalVariable& local,
+                 intptr_t token_pos = Scanner::kNoSourcePos)
+      : local_(local), is_last_(false), token_pos_(token_pos) { }
 
   DECLARE_INSTRUCTION(LoadLocal)
   virtual CompileType ComputeType() const;
@@ -3269,9 +3331,12 @@
   void mark_last() { is_last_ = true; }
   bool is_last() const { return is_last_; }
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   const LocalVariable& local_;
   bool is_last_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
 };
@@ -3296,6 +3361,10 @@
     return EffectSet::None();
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kTempMove;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(PushTempInstr);
 };
@@ -3338,6 +3407,10 @@
     return false;
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kTempMove;
+  }
+
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
     value_ = value;
@@ -3352,8 +3425,10 @@
 
 class StoreLocalInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  StoreLocalInstr(const LocalVariable& local, Value* value)
-      : local_(local), is_dead_(false), is_last_(false) {
+  StoreLocalInstr(const LocalVariable& local,
+                  Value* value,
+                  intptr_t token_pos = Scanner::kNoSourcePos)
+      : local_(local), is_dead_(false), is_last_(false), token_pos_(token_pos) {
     SetInputAt(0, value);
   }
 
@@ -3378,10 +3453,13 @@
     return EffectSet::None();
   }
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   const LocalVariable& local_;
   bool is_dead_;
   bool is_last_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
 };
@@ -3643,7 +3721,8 @@
 
 class LoadStaticFieldInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  explicit LoadStaticFieldInstr(Value* field_value) {
+  LoadStaticFieldInstr(Value* field_value, intptr_t token_pos)
+      : token_pos_(token_pos) {
     ASSERT(field_value->BindsToConstant());
     SetInputAt(0, field_value);
   }
@@ -3664,15 +3743,22 @@
   virtual EffectSet Dependencies() const;
   virtual bool AttributesEqual(Instruction* other) const;
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
+  const intptr_t token_pos_;
+
   DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr);
 };
 
 
 class StoreStaticFieldInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  StoreStaticFieldInstr(const Field& field, Value* value)
-      : field_(field) {
+  StoreStaticFieldInstr(const Field& field,
+                        Value* value,
+                        intptr_t token_pos = Scanner::kNoSourcePos)
+      : field_(field),
+        token_pos_(token_pos) {
     ASSERT(field.IsZoneHandle());
     SetInputAt(kValuePos, value);
   }
@@ -3695,6 +3781,8 @@
   // are marked as having no side-effects.
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   bool CanValueBeSmi() const {
     const intptr_t cid = value()->Type()->ToNullableCid();
@@ -3704,6 +3792,7 @@
   }
 
   const Field& field_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldInstr);
 };
@@ -4719,6 +4808,10 @@
 
   Definition* Canonicalize(FlowGraph* flow_graph);
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kBox;
+  }
+
  protected:
   BoxInstr(Representation from_representation, Value* value)
       : from_representation_(from_representation) {
@@ -4841,6 +4934,10 @@
     return GetDeoptId();
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kBox;
+  }
+
  protected:
   UnboxInstr(Representation representation,
              Value* value,
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 1635611..5c764df 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -696,6 +696,8 @@
 void Isolate::Flags::CopyFrom(const Dart_IsolateFlags& api_flags) {
   type_checks_ = api_flags.enable_type_checks;
   asserts_ = api_flags.enable_asserts;
+  error_on_bad_type_ = api_flags.enable_error_on_bad_type;
+  error_on_bad_override_ = api_flags.enable_error_on_bad_override;
   // Leave others at defaults.
 }
 
@@ -704,6 +706,8 @@
   api_flags->version = DART_FLAGS_CURRENT_VERSION;
   api_flags->enable_type_checks = type_checks();
   api_flags->enable_asserts = asserts();
+  api_flags->enable_error_on_bad_type = error_on_bad_type();
+  api_flags->enable_error_on_bad_override = error_on_bad_override();
 }
 
 
@@ -792,7 +796,9 @@
       pause_loop_monitor_(NULL),
       cha_invalidation_gen_(kInvalidGen),
       field_invalidation_gen_(kInvalidGen),
-      prefix_invalidation_gen_(kInvalidGen) {
+      prefix_invalidation_gen_(kInvalidGen),
+      spawn_count_monitor_(new Monitor()),
+      spawn_count_(0) {
   flags_.CopyFrom(api_flags);
   // TODO(asiva): A Thread is not available here, need to figure out
   // how the vm_tag (kEmbedderTagId) can be set, these tags need to
@@ -824,6 +830,8 @@
   object_id_ring_ = NULL;
   delete pause_loop_monitor_;
   pause_loop_monitor_ = NULL;
+  ASSERT(spawn_count_ == 0);
+  delete spawn_count_monitor_;
   if (compiler_stats_ != NULL) {
     delete compiler_stats_;
     compiler_stats_ = NULL;
@@ -1399,6 +1407,9 @@
 
 static void ShutdownIsolate(uword parameter) {
   Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
+  // We must wait for any outstanding spawn calls to complete before
+  // running the shutdown callback.
+  isolate->WaitForOutstandingSpawns();
   {
     // Print the error if there is one.  This may execute dart code to
     // print the exception object, so we need to use a StartIsolateScope.
@@ -2304,6 +2315,20 @@
 }
 
 
+void Isolate::IncrementSpawnCount() {
+  MonitorLocker ml(spawn_count_monitor_);
+  spawn_count_++;
+}
+
+
+void Isolate::WaitForOutstandingSpawns() {
+  MonitorLocker ml(spawn_count_monitor_);
+  while (spawn_count_ > 0) {
+    ml.Wait();
+  }
+}
+
+
 static RawInstance* DeserializeObject(Thread* thread,
                                       uint8_t* obj_data,
                                       intptr_t obj_len) {
@@ -2331,8 +2356,13 @@
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
                                      Dart_Port origin_id,
                                      void* init_data,
+                                     const char* script_url,
                                      const Function& func,
                                      const Instance& message,
+                                     Monitor* spawn_count_monitor,
+                                     intptr_t* spawn_count,
+                                     const char* package_root,
+                                     const char* package_config,
                                      bool paused,
                                      bool errors_are_fatal,
                                      Dart_Port on_exit_port,
@@ -2343,9 +2373,9 @@
       init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
-      script_url_(NULL),
-      package_root_(NULL),
-      package_map_(NULL),
+      script_url_(script_url),
+      package_root_(package_root),
+      package_config_(package_config),
       library_url_(NULL),
       class_name_(NULL),
       function_name_(NULL),
@@ -2353,6 +2383,8 @@
       serialized_args_len_(0),
       serialized_message_(NULL),
       serialized_message_len_(0),
+      spawn_count_monitor_(spawn_count_monitor),
+      spawn_count_(spawn_count),
       isolate_flags_(),
       paused_(paused),
       errors_are_fatal_(errors_are_fatal) {
@@ -2381,9 +2413,11 @@
                                      void* init_data,
                                      const char* script_url,
                                      const char* package_root,
-                                     const char** package_map,
+                                     const char* package_config,
                                      const Instance& args,
                                      const Instance& message,
+                                     Monitor* spawn_count_monitor,
+                                     intptr_t* spawn_count,
                                      bool paused,
                                      bool errors_are_fatal,
                                      Dart_Port on_exit_port,
@@ -2396,7 +2430,7 @@
       on_error_port_(on_error_port),
       script_url_(script_url),
       package_root_(package_root),
-      package_map_(package_map),
+      package_config_(package_config),
       library_url_(NULL),
       class_name_(NULL),
       function_name_(NULL),
@@ -2404,6 +2438,8 @@
       serialized_args_len_(0),
       serialized_message_(NULL),
       serialized_message_len_(0),
+      spawn_count_monitor_(spawn_count_monitor),
+      spawn_count_(spawn_count),
       isolate_flags_(),
       paused_(paused),
       errors_are_fatal_(errors_are_fatal) {
@@ -2426,14 +2462,7 @@
 IsolateSpawnState::~IsolateSpawnState() {
   delete[] script_url_;
   delete[] package_root_;
-  for (int i = 0; package_map_ != NULL; i++) {
-    if (package_map_[i] != NULL) {
-      delete[] package_map_[i];
-    } else {
-      delete[] package_map_;
-      package_map_ = NULL;
-    }
-  }
+  delete[] package_config_;
   delete[] library_url_;
   delete[] class_name_;
   delete[] function_name_;
@@ -2466,7 +2495,7 @@
     return func.raw();
   }
 
-  ASSERT(script_url() == NULL);
+  // Lookup the to be spawned function for the Isolate.spawn implementation.
   // Resolve the library.
   const String& lib_url = String::Handle(String::New(library_url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
@@ -2521,4 +2550,13 @@
 }
 
 
+void IsolateSpawnState::DecrementSpawnCount() {
+  ASSERT(spawn_count_monitor_ != NULL);
+  ASSERT(spawn_count_ != NULL);
+  MonitorLocker ml(spawn_count_monitor_);
+  ASSERT(*spawn_count_ > 0);
+  *spawn_count_ = *spawn_count_ - 1;
+  ml.Notify();
+}
+
 }  // namespace dart
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 95068b7..8e84d00 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -348,17 +348,6 @@
 
   const Flags& flags() const { return flags_; }
 
-  // Set the checks in the compiler to the highest level. Statically and when
-  // executing generated code. Needs to be called before any code has been
-  // compiled.
-  void set_strict_compilation() {
-    ASSERT(!has_compiled_code());
-    flags_.type_checks_ = true;
-    flags_.asserts_ = true;
-    flags_.error_on_bad_type_ = true;
-    flags_.error_on_bad_override_ = true;
-  }
-
   // Requests that the debugger resume execution.
   void Resume() {
     resume_request_ = true;
@@ -423,6 +412,12 @@
     gc_epilogue_callback_ = callback;
   }
 
+  Monitor* spawn_count_monitor() const { return spawn_count_monitor_; }
+  intptr_t* spawn_count() { return &spawn_count_; }
+
+  void IncrementSpawnCount();
+  void WaitForOutstandingSpawns();
+
   static void SetCreateCallback(Dart_IsolateCreateCallback cb) {
     create_callback_ = cb;
   }
@@ -823,6 +818,11 @@
   uint32_t field_invalidation_gen_;
   uint32_t prefix_invalidation_gen_;
 
+  // This guards spawn_count_. An isolate cannot complete shutdown and be
+  // destroyed while there are child isolates in the midst of a spawn.
+  Monitor* spawn_count_monitor_;
+  intptr_t spawn_count_;
+
 #define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
   type metric_##variable##_;
   ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
@@ -915,8 +915,13 @@
   IsolateSpawnState(Dart_Port parent_port,
                     Dart_Port origin_id,
                     void* init_data,
+                    const char* script_url,
                     const Function& func,
                     const Instance& message,
+                    Monitor* spawn_count_monitor,
+                    intptr_t* spawn_count,
+                    const char* package_root,
+                    const char* package_config,
                     bool paused,
                     bool errorsAreFatal,
                     Dart_Port onExit,
@@ -925,9 +930,11 @@
                     void* init_data,
                     const char* script_url,
                     const char* package_root,
-                    const char** package_map,
+                    const char* package_config,
                     const Instance& args,
                     const Instance& message,
+                    Monitor* spawn_count_monitor,
+                    intptr_t* spawn_count,
                     bool paused,
                     bool errorsAreFatal,
                     Dart_Port onExit,
@@ -944,7 +951,7 @@
   Dart_Port on_error_port() const { return on_error_port_; }
   const char* script_url() const { return script_url_; }
   const char* package_root() const { return package_root_; }
-  const char** package_map() const { return package_map_; }
+  const char* package_config() const { return package_config_; }
   const char* library_url() const { return library_url_; }
   const char* class_name() const { return class_name_; }
   const char* function_name() const { return function_name_; }
@@ -957,6 +964,8 @@
   RawInstance* BuildArgs(Thread* thread);
   RawInstance* BuildMessage(Thread* thread);
 
+  void DecrementSpawnCount();
+
  private:
   Isolate* isolate_;
   Dart_Port parent_port_;
@@ -966,7 +975,7 @@
   Dart_Port on_error_port_;
   const char* script_url_;
   const char* package_root_;
-  const char** package_map_;
+  const char* package_config_;
   const char* library_url_;
   const char* class_name_;
   const char* function_name_;
@@ -974,6 +983,12 @@
   intptr_t serialized_args_len_;
   uint8_t* serialized_message_;
   intptr_t serialized_message_len_;
+
+  // This counter tracks the number of outstanding calls to spawn by the parent
+  // isolate.
+  Monitor* spawn_count_monitor_;
+  intptr_t* spawn_count_;
+
   Isolate::Flags isolate_flags_;
   bool paused_;
   bool errors_are_fatal_;
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index d5d87cf..1caee52 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -74,7 +74,7 @@
 
 
   result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL);
-  EXPECT(!Dart_IsError(result));
+  EXPECT_VALID(result);
   // Run until all ports to isolate are closed.
   result = Dart_RunLoop();
   EXPECT_ERROR(result,
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index ba0e438..c878847 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -15,7 +15,7 @@
 #define OTHER_RECOGNIZED_LIST(V)                                               \
   V(::, identical, ObjectIdentical, 554128144)                                 \
   V(ClassID, getID, ClassIDgetID, 535124072)                                   \
-  V(Object, Object., ObjectConstructor, 1066759160)                            \
+  V(Object, Object., ObjectConstructor, 1852396454)                            \
   V(_List, ., ObjectArrayAllocate, 850375012)                                  \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1541411498)                    \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1032404349)                  \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 4e8e2ddf..4e43f45 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2637,7 +2637,7 @@
                     false,  // Not external.
                     false,  // Not native.
                     *this,
-                    0));  // No token position.
+                    0));    // token_pos
   ArgumentsDescriptor desc(args_desc);
   invocation.set_num_fixed_parameters(desc.PositionalCount());
   invocation.SetNumOptionalParameters(desc.NamedCount(),
@@ -2694,7 +2694,7 @@
                   false,  // Not external.
                   false,  // Not native.
                   owner,
-                  0));  // No token position.
+                  0));    // token_pos
 
   // Initialize signature: receiver is a single fixed parameter.
   const intptr_t kNumParameters = 1;
@@ -3449,7 +3449,7 @@
 
 
 void Class::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -4379,7 +4379,7 @@
 
 
 void UnresolvedClass::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -5780,9 +5780,9 @@
 }
 
 
-void Function::set_token_pos(intptr_t value) const {
-  ASSERT(value >= 0);
-  StoreNonPointer(&raw_ptr()->token_pos_, value);
+void Function::set_token_pos(intptr_t token_pos) const {
+  ASSERT(token_pos >= 0);
+  StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
@@ -5872,13 +5872,8 @@
 
 intptr_t Function::NumImplicitParameters() const {
   if (kind() == RawFunction::kConstructor) {
-    if (is_static()) {
-      ASSERT(IsFactory());
-      return 1;  // Type arguments.
-    } else {
-      ASSERT(IsGenerativeConstructor());
-      return 2;  // Instance, phase.
-    }
+    // Type arguments for factory; instance for generative constructor.
+    return 1;
   }
   if ((kind() == RawFunction::kClosureFunction) ||
       (kind() == RawFunction::kSignatureFunction)) {
@@ -6257,10 +6252,7 @@
   const intptr_t other_num_opt_named_params =
       other.NumOptionalNamedParameters();
   // This function requires the same arguments or less and accepts the same
-  // arguments or more.
-  // A generative constructor may be compared to a redirecting factory and be
-  // compatible although it has an additional phase parameter.
-  // More generally, we can ignore implicit parameters.
+  // arguments or more. We can ignore implicit parameters.
   const intptr_t num_ignored_params = NumImplicitParameters();
   const intptr_t other_num_ignored_params = other.NumImplicitParameters();
   if (((num_fixed_params - num_ignored_params) >
@@ -6519,7 +6511,7 @@
                     /* is_external = */ false,
                     /* is_native = */ false,
                     owner,
-                    0));
+                    /* token_pos = */ 0));
   ASSERT(!script.IsNull());
   result.set_is_debuggable(false);
   result.set_is_visible(true);
@@ -14572,9 +14564,9 @@
 }
 
 
-void LanguageError::set_token_pos(intptr_t value) const {
-  ASSERT(value >= 0);
-  StoreNonPointer(&raw_ptr()->token_pos_, value);
+void LanguageError::set_token_pos(intptr_t token_pos) const {
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
@@ -16389,7 +16381,7 @@
 
 
 void Type::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -16820,7 +16812,7 @@
 
 
 void TypeParameter::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -21582,7 +21574,7 @@
   const String& url = String::Handle(zone, script.url());
   intptr_t line = -1;
   intptr_t column = -1;
-  if (token_pos > 0) {
+  if (token_pos >= 0) {
     if (script.HasSource()) {
       script.GetTokenLocation(token_pos, &line, &column);
     } else {
@@ -21608,6 +21600,23 @@
 }
 
 
+static intptr_t PrintOneStacktraceNoCode(Zone* zone,
+                                         GrowableArray<char*>* frame_strings,
+                                         const Function& function,
+                                         intptr_t frame_index) {
+  const Script& script = Script::Handle(zone, function.script());
+  const String& function_name =
+      String::Handle(zone, function.QualifiedUserVisibleName());
+  const String& url = String::Handle(zone, script.url());
+  char* chars = NULL;
+  chars = OS::SCreate(zone,
+      "#%-6" Pd " %s (%s)\n",
+      frame_index, function_name.ToCString(), url.ToCString());
+  frame_strings->Add(chars);
+  return strlen(chars);
+}
+
+
 const char* Stacktrace::ToCStringInternal(intptr_t* frame_index,
                                           intptr_t max_frames) const {
   Zone* zone = Thread::Current()->zone();
@@ -21620,7 +21629,8 @@
   for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) {
     function = FunctionAtFrame(i);
     if (function.IsNull()) {
-      // Check if null function object indicates a stack trace overflow.
+      // Check if null function object indicates a gap in a StackOverflow or
+      // OutOfMemory trace.
       if ((i < (Length() - 1)) &&
           (FunctionAtFrame(i + 1) != Function::null())) {
         const char* kTruncated = "...\n...\n";
@@ -21630,31 +21640,55 @@
         frame_strings.Add(chars);
         total_len += truncated_len;
       }
-    } else if (function.is_visible() || FLAG_show_invisible_frames) {
+    } else {
       code = CodeAtFrame(i);
       ASSERT(function.raw() == code.function());
       uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
       if (code.is_optimized() && expand_inlined()) {
         // Traverse inlined frames.
-        for (InlinedFunctionsIterator it(code, pc);
-             !it.Done() && (*frame_index < max_frames); it.Advance()) {
-          function = it.function();
-          if (function.is_visible() || FLAG_show_invisible_frames) {
-            code = it.code();
-            ASSERT(function.raw() == code.function());
-            uword pc = it.pc();
-            ASSERT(pc != 0);
-            ASSERT(code.EntryPoint() <= pc);
-            ASSERT(pc < (code.EntryPoint() + code.Size()));
-            total_len += PrintOneStacktrace(
-                zone, &frame_strings, pc, function, code, *frame_index);
-            (*frame_index)++;  // To account for inlined frames.
+        if (Compiler::allow_recompilation()) {
+          for (InlinedFunctionsIterator it(code, pc);
+               !it.Done() && (*frame_index < max_frames); it.Advance()) {
+            function = it.function();
+            if (function.is_visible() || FLAG_show_invisible_frames) {
+              code = it.code();
+              ASSERT(function.raw() == code.function());
+              uword pc = it.pc();
+              ASSERT(pc != 0);
+              ASSERT(code.EntryPoint() <= pc);
+              ASSERT(pc < (code.EntryPoint() + code.Size()));
+              total_len += PrintOneStacktrace(
+                  zone, &frame_strings, pc, function, code, *frame_index);
+              (*frame_index)++;  // To account for inlined frames.
+            }
+          }
+        } else {
+          // Precompilation: we don't have deopt info, so we don't know the
+          // source position of inlined functions, but we can still name them.
+          intptr_t offset = Smi::Value(PcOffsetAtFrame(i));
+          // The PC of frames below the top frame is a call's return address,
+          // which can belong to a different inlining interval than the call.
+          intptr_t effective_offset = offset - 1;
+          GrowableArray<Function*> inlined_functions;
+          code.GetInlinedFunctionsAt(effective_offset, &inlined_functions);
+          ASSERT(inlined_functions.length() >= 1);  // At least the inliner.
+          for (intptr_t j = 0; j < inlined_functions.length(); j++) {
+            Function* inlined_function = inlined_functions[j];
+            ASSERT(inlined_function != NULL);
+            ASSERT(!inlined_function->IsNull());
+            if (inlined_function->is_visible() || FLAG_show_invisible_frames) {
+              total_len += PrintOneStacktraceNoCode(
+                  zone, &frame_strings, *inlined_function, *frame_index);
+              (*frame_index)++;
+            }
           }
         }
       } else {
-        total_len += PrintOneStacktrace(
-            zone, &frame_strings, pc, function, code, *frame_index);
-        (*frame_index)++;
+        if (function.is_visible() || FLAG_show_invisible_frames) {
+          total_len += PrintOneStacktrace(
+              zone, &frame_strings, pc, function, code, *frame_index);
+          (*frame_index)++;
+        }
       }
     }
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index b223be2..5d3c509 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2654,10 +2654,6 @@
   // Sets deopt reason in all ICData-s with given deopt_id.
   void SetDeoptReasonForAll(intptr_t deopt_id, ICData::DeoptReasonId reason);
 
-  static const int kCtorPhaseInit = 1 << 0;
-  static const int kCtorPhaseBody = 1 << 1;
-  static const int kCtorPhaseAll = (kCtorPhaseInit | kCtorPhaseBody);
-
   void set_modifier(RawFunction::AsyncModifier value) const;
 
   // static: Considered during class-side or top-level resolution rather than
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 1e055f4..603ade6 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -19,6 +19,9 @@
 
 namespace dart {
 
+// Defined in vm/os_thread_win.cc
+extern bool private_flag_windows_run_tls_destructors;
+
 const char* OS::Name() {
   return "windows";
 }
@@ -404,12 +407,18 @@
 
 
 void OS::Abort() {
+  // TODO(zra): Remove once VM shuts down cleanly.
+  private_flag_windows_run_tls_destructors = false;
   abort();
 }
 
 
 void OS::Exit(int code) {
-  exit(code);
+  // TODO(zra): Remove once VM shuts down cleanly.
+  private_flag_windows_run_tls_destructors = false;
+  // On Windows we use ExitProcess so that threads can't clobber the exit_code.
+  // See: https://code.google.com/p/nativeclient/issues/detail?id=2870
+  ::ExitProcess(code);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index a0a0aec..981b84b 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -48,9 +48,12 @@
 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
 DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily");
-DEFINE_FLAG(bool, move_super, true, "Move super initializer to end of list.");
+DEFINE_FLAG(bool, conditional_directives, false,
+    "Enable conditional directives");
 DEFINE_FLAG(bool, warn_super, false,
     "Warning if super initializer not last in initializer list.");
+DEFINE_FLAG(bool, await_is_keyword, false,
+    "await and yield are treated as proper keywords in synchronous code.");
 
 DECLARE_FLAG(bool, lazy_dispatchers);
 DECLARE_FLAG(bool, load_deferred_eagerly);
@@ -236,7 +239,7 @@
 
 struct CatchParamDesc {
   CatchParamDesc()
-      : token_pos(0), type(NULL), name(NULL), var(NULL) { }
+      : token_pos(Scanner::kNoSourcePos), type(NULL), name(NULL), var(NULL) { }
   intptr_t token_pos;
   const AbstractType* type;
   const String* name;
@@ -390,7 +393,7 @@
     const GrowableObjectArray& pending_functions =
         GrowableObjectArray::Handle(T->pending_functions());
     ASSERT(pending_functions.Length() > 0);
-    ASSERT(pending_functions.At(pending_functions.Length()-1) ==
+    ASSERT(pending_functions.At(pending_functions.Length() - 1) ==
         current_function().raw());
     pending_functions.RemoveLast();
   }
@@ -515,7 +518,7 @@
 struct ParamDesc {
   ParamDesc()
       : type(NULL),
-        name_pos(0),
+        name_pos(Scanner::kNoSourcePos),
         name(NULL),
         default_value(NULL),
         metadata(NULL),
@@ -620,10 +623,10 @@
     has_factory = false;
     has_operator = false;
     has_native = false;
-    metadata_pos = -1;
+    metadata_pos = Scanner::kNoSourcePos;
     operator_token = Token::kILLEGAL;
     type = NULL;
-    name_pos = 0;
+    name_pos = Scanner::kNoSourcePos;
     name = NULL;
     redirect_name = NULL;
     dict_name = NULL;
@@ -950,13 +953,11 @@
   switch (func.kind()) {
     case RawFunction::kClosureFunction:
       if (func.IsImplicitClosureFunction()) {
-        node_sequence =
-            parser.ParseImplicitClosure(func);
+        node_sequence = parser.ParseImplicitClosure(func);
         break;
       }
       if (func.IsConstructorClosureFunction()) {
-        node_sequence =
-            parser.ParseConstructorClosure(func);
+        node_sequence = parser.ParseConstructorClosure(func);
         break;
       }
       // Fall-through: Handle non-implicit closures.
@@ -1369,8 +1370,8 @@
   ASSERT(!constructor.IsNull());
 
   ParamList params;
-  // The first parameter of the closure function is the implicit closure
-  // argument.
+  // The first parameter of the closure function is the
+  // implicit closure argument.
   params.AddFinalParameter(token_pos,
                            &Symbols::ClosureParameter(),
                            &Object::dynamic_type());
@@ -2372,7 +2373,6 @@
       const Class& cls,
       intptr_t supercall_pos,
       LocalVariable* receiver,
-      AstNode* phase_parameter,
       ArgumentListNode* forwarding_args) {
   const Class& super_class = Class::Handle(Z, cls.SuperClass());
   // Omit the implicit super() if there is no super class (i.e.
@@ -2390,8 +2390,6 @@
   // Implicit 'this' parameter is the first argument.
   AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
   arguments->Add(implicit_argument);
-  // Implicit construction phase parameter is second argument.
-  arguments->Add(phase_parameter);
 
   // If this is a super call in a forwarding constructor, add the user-
   // defined arguments to the super call and adjust the the super
@@ -2457,14 +2455,7 @@
   // 'this' parameter is the first argument to super class constructor.
   AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
   arguments->Add(implicit_argument);
-  // Second implicit parameter is the construction phase. We optimistically
-  // assume that we can execute both the super initializer and the super
-  // constructor body. We may later change this to only execute the
-  // super initializer.
-  AstNode* phase_parameter =
-      new LiteralNode(supercall_pos,
-                      Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll)));
-  arguments->Add(phase_parameter);
+
   // 'this' parameter must not be accessible to the other super call arguments.
   receiver->set_invisible(true);
   ParseActualParameters(arguments, kAllowConst);
@@ -2792,17 +2783,15 @@
   if (super_init_call == NULL) {
     // Generate implicit super() if we haven't seen an explicit super call
     // or constructor redirection.
-    AstNode* phase_parameter = new LiteralNode(
-        TokenPos(), Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll)));
-    super_init_call = GenerateSuperConstructorCall(
-        cls, TokenPos(), receiver, phase_parameter, NULL);
+    super_init_call =
+        GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL);
     if (super_init_call != NULL) {
       super_init_index = current_block_->statements->length();
       current_block_->statements->Add(super_init_call);
       super_init_is_last = true;
     }
   }
-  if (FLAG_move_super && (super_init_call != NULL) && !super_init_is_last) {
+  if ((super_init_call != NULL) && !super_init_is_last) {
     // If the super initializer call is not at the end of the initializer
     // list, implicitly move it to the end. The actual parameter values
     // are evaluated at the original position in the list and preserved
@@ -2818,10 +2807,10 @@
     ASSERT(super_init_index >= 0);
     ArgumentListNode* ctor_args = super_init_call->arguments();
     LetNode* saved_args = new(Z) LetNode(super_init_call->token_pos());
-    // The super initializer call has at least 2 arguments: the
-    // implicit receiver, and the hidden construction phase.
-    ASSERT(ctor_args->length() >= 2);
-    for (int i = 2; i < ctor_args->length(); i++) {
+    // The super initializer call has at least 1 arguments: the
+    // implicit receiver.
+    ASSERT(ctor_args->length() >= 1);
+    for (int i = 1; i < ctor_args->length(); i++) {
       AstNode* arg = ctor_args->NodeAt(i);
       LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca");
       AstNode* save_temp = new(Z) StoreLocalNode(arg->token_pos(), temp, arg);
@@ -2857,11 +2846,7 @@
   // 'this' parameter is the first argument to constructor.
   AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver);
   arguments->Add(implicit_argument);
-  // Construction phase parameter is second argument.
-  LocalVariable* phase_param = LookupPhaseParameter();
-  ASSERT(phase_param != NULL);
-  AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param);
-  arguments->Add(phase_argument);
+
   receiver->set_invisible(true);
   ParseActualParameters(arguments, kAllowConst);
   receiver->set_invisible(false);
@@ -2895,12 +2880,6 @@
       Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class()));
   current_block_->scope->InsertParameterAt(0, receiver);
 
-  LocalVariable* phase_parameter =
-      new LocalVariable(Scanner::kNoSourcePos,
-                        Symbols::PhaseParameter(),
-                        Type::ZoneHandle(Z, Type::SmiType()));
-  current_block_->scope->InsertParameterAt(1, phase_parameter);
-
   // Parse expressions of instance fields that have an explicit
   // initializer expression.
   // The receiver must not be visible to field initializer expressions.
@@ -2940,9 +2919,9 @@
     }
 
     // Prepare user-defined arguments to be forwarded to super call.
-    // The first user-defined argument is at position 2.
+    // The first user-defined argument is at position 1.
     forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos);
-    for (int i = 2; i < func.NumParameters(); i++) {
+    for (int i = 1; i < func.NumParameters(); i++) {
       LocalVariable* param = new LocalVariable(
           Scanner::kNoSourcePos,
           String::ZoneHandle(Z, func.ParameterNameAt(i)),
@@ -2956,7 +2935,6 @@
       current_class(),
       Scanner::kNoSourcePos,
       receiver,
-      new LoadLocalNode(Scanner::kNoSourcePos, phase_parameter),
       forwarding_args);
   if (super_call != NULL) {
     current_block_->statements->Add(super_call);
@@ -3019,12 +2997,6 @@
   ASSERT(current_class().raw() == func.Owner());
   params.AddReceiver(ReceiverType(current_class()), func.token_pos());
 
-  // Add implicit parameter for construction phase.
-  params.AddFinalParameter(
-      TokenPos(),
-      &Symbols::PhaseParameter(),
-      &Type::ZoneHandle(Z, Type::SmiType()));
-
   if (func.is_const()) {
     params.SetImplicitlyFinal();
   }
@@ -3064,9 +3036,9 @@
 
   // Turn formal field parameters into field initializers.
   if (params.has_field_initializer) {
-    // First two parameters are implicit receiver and phase.
-    ASSERT(params.parameters->length() >= 2);
-    for (int i = 2; i < params.parameters->length(); i++) {
+    // The first parameter is the implicit receiver.
+    ASSERT(params.parameters->length() >= 1);
+    for (int i = 1; i < params.parameters->length(); i++) {
       ParamDesc& param = (*params.parameters)[i];
       if (param.is_field_initializer) {
         const String& field_name = *param.name;
@@ -3123,124 +3095,10 @@
   }
 
   SequenceNode* init_statements = CloseBlock();
-  if (FLAG_move_super) {
-    // Ignore the phase parameter.
-    current_block_->statements->Add(init_statements);
-  } else if (is_redirecting_constructor) {
-    // A redirecting super constructor simply passes the phase parameter on to
-    // the target which executes the corresponding phase.
-    current_block_->statements->Add(init_statements);
-  } else if (init_statements->length() > 0) {
-    // Generate guard around the initializer code.
-    LocalVariable* phase_param = LookupPhaseParameter();
-    AstNode* phase_value = new
-        LoadLocalNode(Scanner::kNoSourcePos, phase_param);
-    AstNode* phase_check = new BinaryOpNode(
-        Scanner::kNoSourcePos, Token::kBIT_AND, phase_value,
-        new LiteralNode(Scanner::kNoSourcePos,
-            Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit))));
-    AstNode* comparison =
-        new ComparisonNode(Scanner::kNoSourcePos,
-                           Token::kNE_STRICT,
-                           phase_check,
-                           new LiteralNode(TokenPos(),
-                                           Smi::ZoneHandle(Z, Smi::New(0))));
-    AstNode* guarded_init_statements =
-        new IfNode(Scanner::kNoSourcePos,
-                   comparison,
-                   init_statements,
-                   NULL);
-    current_block_->statements->Add(guarded_init_statements);
-  }
+  current_block_->statements->Add(init_statements);
 
-  // Parsing of initializers done. Now we parse the constructor body
-  // and add the implicit super call to the super constructor's body
-  // if necessary.
-  StaticCallNode* super_call = NULL;
-  // Look for the super initializer call in the sequence of initializer
-  // statements. If it exists and is not the last initializer statement,
-  // we need to create an implicit super call to the super constructor's
-  // body.
-  // Thus, iterate over all but the last initializer to see whether
-  // it's a super constructor call.
-  for (int i = 0; i < init_statements->length() - 1; i++) {
-    if (init_statements->NodeAt(i)->IsStaticCallNode()) {
-      StaticCallNode* static_call =
-      init_statements->NodeAt(i)->AsStaticCallNode();
-      if (static_call->function().IsGenerativeConstructor()) {
-        super_call = static_call;
-        break;
-      }
-    }
-  }
-  if (super_call != NULL) {
-    ASSERT(!FLAG_move_super);
-    // Generate an implicit call to the super constructor's body.
-    // We need to patch the super _initializer_ call so that it
-    // saves the evaluated actual arguments in temporary variables.
-    // The temporary variables are necessary so that the argument
-    // expressions are not evaluated twice.
-    // Note: we should never get here in the case of a redirecting
-    // constructor. In that case, the call to the target constructor
-    // is the "super call" and is implicitly at the end of the
-    // initializer list.
-    ASSERT(!is_redirecting_constructor);
-    ArgumentListNode* ctor_args = super_call->arguments();
-    // The super initializer call has at least 2 arguments: the
-    // implicit receiver, and the hidden construction phase.
-    ASSERT(ctor_args->length() >= 2);
-    for (int i = 2; i < ctor_args->length(); i++) {
-      AstNode* arg = ctor_args->NodeAt(i);
-      if (!IsSimpleLocalOrLiteralNode(arg)) {
-        LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca");
-        AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg);
-        ctor_args->SetNodeAt(i, save_temp);
-      }
-    }
-  }
+  // Parsing of initializers done. Now we parse the constructor body.
   OpenBlock();  // Block to collect constructor body nodes.
-  intptr_t body_pos = TokenPos();
-
-  // Insert the implicit super call to the super constructor body.
-  if (super_call != NULL) {
-    ASSERT(!FLAG_move_super);
-    ArgumentListNode* initializer_args = super_call->arguments();
-    const Function& super_ctor = super_call->function();
-    // Patch the initializer call so it only executes the super initializer.
-    initializer_args->SetNodeAt(1, new LiteralNode(
-        body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit))));
-
-    ArgumentListNode* super_call_args = new ArgumentListNode(body_pos);
-    // First argument is the receiver.
-    super_call_args->Add(new LoadLocalNode(body_pos, receiver));
-    // Second argument is the construction phase argument.
-    AstNode* phase_parameter = new(Z) LiteralNode(
-        body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseBody)));
-    super_call_args->Add(phase_parameter);
-    super_call_args->set_names(initializer_args->names());
-    for (int i = 2; i < initializer_args->length(); i++) {
-      AstNode* arg = initializer_args->NodeAt(i);
-      if (arg->IsLiteralNode()) {
-        LiteralNode* lit = arg->AsLiteralNode();
-        super_call_args->Add(new LiteralNode(body_pos, lit->literal()));
-      } else {
-        ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
-        if (arg->IsLoadLocalNode()) {
-          const LocalVariable& temp = arg->AsLoadLocalNode()->local();
-          super_call_args->Add(new LoadLocalNode(body_pos, &temp));
-        } else if (arg->IsStoreLocalNode()) {
-          const LocalVariable& temp = arg->AsStoreLocalNode()->local();
-          super_call_args->Add(new LoadLocalNode(body_pos, &temp));
-        }
-      }
-    }
-    ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
-                                        super_call_args->names(),
-                                        NULL));
-    current_block_->statements->Add(
-        new StaticCallNode(body_pos, super_ctor, super_call_args));
-  }
-
   if (CurrentToken() == Token::kLBRACE) {
     // We checked in the top-level parse phase that a redirecting
     // constructor does not have a body.
@@ -3273,29 +3131,7 @@
 
   SequenceNode* ctor_block = CloseBlock();
   if (ctor_block->length() > 0) {
-    if (FLAG_move_super) {
-      // Ignore the phase parameter.
-      current_block_->statements->Add(ctor_block);
-    } else {
-      // Generate guard around the constructor body code.
-      LocalVariable* phase_param = LookupPhaseParameter();
-      AstNode* phase_value =
-          new LoadLocalNode(Scanner::kNoSourcePos, phase_param);
-      AstNode* phase_check =
-          new BinaryOpNode(Scanner::kNoSourcePos, Token::kBIT_AND,
-              phase_value,
-              new LiteralNode(Scanner::kNoSourcePos,
-                  Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
-      AstNode* comparison =
-          new ComparisonNode(Scanner::kNoSourcePos,
-                             Token::kNE_STRICT,
-                             phase_check,
-                             new LiteralNode(body_pos,
-                                             Smi::ZoneHandle(Smi::New(0))));
-      AstNode* guarded_block_statements =
-          new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL);
-      current_block_->statements->Add(guarded_block_statements);
-    }
+    current_block_->statements->Add(ctor_block);
   }
   current_block_->statements->Add(new ReturnNode(func.end_token_pos()));
   SequenceNode* statements = CloseBlock();
@@ -3483,7 +3319,7 @@
 
   BoolScope allow_await(&this->await_is_keyword_,
                         func.IsAsyncOrGenerator() || func.is_generated_body());
-  intptr_t end_token_pos = 0;
+  intptr_t end_token_pos = Scanner::kNoSourcePos;
   if (CurrentToken() == Token::kLBRACE) {
     ConsumeToken();
     if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
@@ -3715,13 +3551,6 @@
         &Symbols::TypeArgumentsParameter(),
         &Object::dynamic_type());
   }
-  // Constructors have an implicit parameter for the construction phase.
-  if (method->IsConstructor()) {
-    method->params.AddFinalParameter(
-        TokenPos(),
-        &Symbols::PhaseParameter(),
-        &Type::ZoneHandle(Z, Type::SmiType()));
-  }
   if (are_implicitly_final) {
     method->params.SetImplicitlyFinal();
   }
@@ -4004,7 +3833,7 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) {
     func.set_is_reflectable(false);
   }
-  if (FLAG_enable_mirrors && (method->metadata_pos > 0)) {
+  if (FLAG_enable_mirrors && (method->metadata_pos >= 0)) {
     library_.AddFunctionMetadata(func, method->metadata_pos);
   }
   if (method->has_native) {
@@ -4035,7 +3864,7 @@
          CurrentToken() == Token::kCOMMA ||
          CurrentToken() == Token::kASSIGN);
   ASSERT(field->type != NULL);
-  ASSERT(field->name_pos > 0);
+  ASSERT(field->name_pos >= 0);
   ASSERT(current_member_ == field);
   // All const fields are also final.
   ASSERT(!field->has_const || field->has_final);
@@ -4463,8 +4292,8 @@
                                   const Object& tl_owner,
                                   intptr_t metadata_pos) {
   TRACE_PARSER("ParseEnumDeclaration");
-  const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos
-                                                      : TokenPos();
+  const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos
+                                                       : TokenPos();
   ConsumeToken();
   const intptr_t name_pos = TokenPos();
   String* enum_name =
@@ -4515,7 +4344,7 @@
   TRACE_PARSER("ParseClassDeclaration");
   bool is_patch = false;
   bool is_abstract = false;
-  intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos();
+  intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos();
   if (is_patch_source() &&
       (CurrentToken() == Token::kIDENT) &&
       CurrentLiteral()->Equals("patch")) {
@@ -4958,10 +4787,6 @@
   // Add implicit 'this' parameter.
   const AbstractType* receiver_type = ReceiverType(cls);
   params.AddReceiver(receiver_type, cls.token_pos());
-  // Add implicit parameter for construction phase.
-  params.AddFinalParameter(cls.token_pos(),
-                           &Symbols::PhaseParameter(),
-                           &Type::ZoneHandle(Z, Type::SmiType()));
 
   AddFormalParamsToFunction(&params, ctor);
   // The body of the constructor cannot modify the type of the constructed
@@ -5107,7 +4932,7 @@
                           const Object& tl_owner,
                           intptr_t metadata_pos) {
   TRACE_PARSER("ParseTypedef");
-  intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos();
+  intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos();
   ExpectToken(Token::kTYPEDEF);
 
   if (IsMixinAppAlias()) {
@@ -5248,7 +5073,7 @@
 
 intptr_t Parser::SkipMetadata() {
   if (CurrentToken() != Token::kAT) {
-    return -1;
+    return Scanner::kNoSourcePos;
   }
   intptr_t metadata_pos = TokenPos();
   while (CurrentToken() == Token::kAT) {
@@ -5316,8 +5141,8 @@
       ConsumeToken();
       const intptr_t metadata_pos = SkipMetadata();
       const intptr_t type_parameter_pos = TokenPos();
-      const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos
-                                                          : type_parameter_pos;
+      const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos
+                                                           : type_parameter_pos;
       String& type_parameter_name =
           *ExpectUserDefinedTypeIdentifier("type parameter expected");
       // Check for duplicate type parameters.
@@ -5947,6 +5772,53 @@
   ConsumeToken();
   CheckToken(Token::kSTRING, "library url expected");
   AstNode* url_literal = ParseStringLiteral(false);
+  if (FLAG_conditional_directives) {
+    bool condition_triggered = false;
+    while (CurrentToken() == Token::kIF) {
+      // Conditional import: if (env == val) uri.
+      ConsumeToken();
+      ExpectToken(Token::kLPAREN);
+      // Parse dotted name.
+      const GrowableObjectArray& pieces =
+          GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+      pieces.Add(*ExpectIdentifier("identifier expected"));
+      while (CurrentToken() == Token::kPERIOD) {
+        pieces.Add(Symbols::Dot());
+        ConsumeToken();
+        pieces.Add(*ExpectIdentifier("identifier expected"));
+      }
+      AstNode* valueNode = NULL;
+      if (CurrentToken() == Token::kEQ) {
+        ConsumeToken();
+        CheckToken(Token::kSTRING, "string literal expected");
+        valueNode = ParseStringLiteral(false);
+        ASSERT(valueNode->IsLiteralNode());
+        ASSERT(valueNode->AsLiteralNode()->literal().IsString());
+      }
+      ExpectToken(Token::kRPAREN);
+      CheckToken(Token::kSTRING, "library url expected");
+      AstNode* conditional_url_literal = ParseStringLiteral(false);
+
+      // If there was already a condition that triggered, don't try to match
+      // again.
+      if (condition_triggered) {
+        continue;
+      }
+      // Check if this conditional line overrides the default import.
+      const String& key = String::Handle(
+          String::ConcatAll(Array::Handle(Array::MakeArray(pieces))));
+      const String& value = (valueNode == NULL)
+          ? Symbols::True()
+          : String::Cast(valueNode->AsLiteralNode()->literal());
+      // Call the embedder to supply us with the environment.
+      const String& env_value =
+          String::Handle(Api::CallEnvironmentCallback(T, key));
+      if (!env_value.IsNull() && env_value.Equals(value)) {
+        condition_triggered = true;
+        url_literal = conditional_url_literal;
+      }
+    }
+  }
   ASSERT(url_literal->IsLiteralNode());
   ASSERT(url_literal->AsLiteralNode()->literal().IsString());
   const String& url = String::Cast(url_literal->AsLiteralNode()->literal());
@@ -5960,7 +5832,7 @@
     CheckToken(Token::kAS, "'as' expected");
   }
   String& prefix = String::Handle(Z);
-  intptr_t prefix_pos = 0;
+  intptr_t prefix_pos = Scanner::kNoSourcePos;
   if (is_import && (CurrentToken() == Token::kAS)) {
     ConsumeToken();
     prefix_pos = TokenPos();
@@ -6415,7 +6287,9 @@
 
     // Suspend after the close.
     AwaitMarkerNode* await_marker =
-        new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
+        new(Z) AwaitMarkerNode(async_temp_scope_,
+                               current_block_->scope,
+                               Scanner::kNoSourcePos);
     current_block_->statements->Add(await_marker);
     ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
     continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
@@ -6465,7 +6339,8 @@
                           context_var,
                           catch_clause,
                           finally_clause,
-                          try_index);
+                          try_index,
+                          finally_clause);
   current_block_->statements->Add(try_catch_node);
   return CloseBlock();
 }
@@ -6581,7 +6456,8 @@
       context_var,
       catch_clause,
       NULL,  // No finally clause.
-      try_index);
+      try_index,
+      NULL);  // No rethrow-finally clause.
   current_block_->statements->Add(try_catch_node);
   return CloseBlock();
 }
@@ -7439,13 +7315,6 @@
 }
 
 
-LocalVariable* Parser::LookupPhaseParameter() {
-  const bool kTestOnly = false;
-  return current_block_->scope->LookupVariable(Symbols::PhaseParameter(),
-                                               kTestOnly);
-}
-
-
 void Parser::CaptureInstantiator() {
   ASSERT(current_block_->scope->function_level() > 0);
   const String* variable_name = current_function().IsInFactoryScope() ?
@@ -7644,7 +7513,7 @@
   result_type = Type::DynamicType();
 
   const intptr_t function_pos = TokenPos();
-  intptr_t metadata_pos = -1;
+  intptr_t metadata_pos = Scanner::kNoSourcePos;
   if (is_literal) {
     ASSERT(CurrentToken() == Token::kLPAREN);
     function_name = &Symbols::AnonymousClosure();
@@ -8936,7 +8805,8 @@
                          context_var,
                          catch_clause,
                          finally_clause,
-                         try_index);
+                         try_index,
+                         finally_clause);
 
   ASSERT(current_block_ == loop_block);
   loop_block->statements->Add(try_catch_node);
@@ -8953,7 +8823,7 @@
     ReportError("Loop variable cannot be 'const'");
   }
   const String* loop_var_name = NULL;
-  intptr_t loop_var_pos = 0;
+  intptr_t loop_var_pos = Scanner::kNoSourcePos;
   bool new_loop_var = false;
   AbstractType& loop_var_type =  AbstractType::ZoneHandle(Z);
   if (LookaheadToken(1) == Token::kIN) {
@@ -9762,6 +9632,7 @@
   // of an existing outer try. Generate a finally clause to this purpose if it
   // is not declared.
   SequenceNode* finally_clause = NULL;
+  SequenceNode* rethrow_clause = NULL;
   const bool parse = CurrentToken() == Token::kFINALLY;
   if (parse || (is_async && (try_stack_ != NULL))) {
     if (parse) {
@@ -9795,6 +9666,21 @@
         stack_trace_var,
         is_async ? saved_exception_var : exception_var,
         is_async ? saved_stack_trace_var : stack_trace_var);
+    if (finally_clause != NULL) {
+      // Re-parse to create a duplicate of finally clause to avoid unintended
+      // sharing of try-indices if the finally-block contains a try-catch.
+      // The flow graph builder emits two copies of the finally-block if the
+      // try-block has a normal exit: one for the exception- and one for the
+      // non-exception case (see EffectGraphVisitor::VisitTryCatchNode)
+      tokens_iterator_.SetCurrentPosition(finally_pos);
+      rethrow_clause = EnsureFinallyClause(
+          parse,
+          is_async,
+          exception_var,
+          stack_trace_var,
+          is_async ? saved_exception_var : exception_var,
+          is_async ? saved_stack_trace_var : stack_trace_var);
+    }
   }
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
@@ -9814,7 +9700,8 @@
   // on the try/catch, close the block that's embedding the try statement
   // and attach the label to it.
   AstNode* try_catch_node = new(Z) TryCatchNode(
-      try_pos, try_block, context_var, catch_clause, finally_clause, try_index);
+      try_pos, try_block, context_var, catch_clause, finally_clause, try_index,
+      rethrow_clause);
 
   if (try_label != NULL) {
     current_block_->statements->Add(try_catch_node);
@@ -9938,7 +9825,9 @@
       yield->AddNode(set_is_yield_each);
     }
     AwaitMarkerNode* await_marker =
-        new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
+        new(Z) AwaitMarkerNode(async_temp_scope_,
+                               current_block_->scope,
+                               Scanner::kNoSourcePos);
     yield->AddNode(await_marker);
     // Return true to indicate that a value has been generated.
     ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
@@ -10006,7 +9895,9 @@
     yield->AddNode(if_is_cancelled);
 
     AwaitMarkerNode* await_marker =
-        new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
+        new(Z) AwaitMarkerNode(async_temp_scope_,
+                               current_block_->scope,
+                               Scanner::kNoSourcePos);
     yield->AddNode(await_marker);
     ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
     continuation_return->set_return_type(ReturnNode::kContinuationTarget);
@@ -10047,14 +9938,14 @@
 AstNode* Parser::ParseStatement() {
   TRACE_PARSER("ParseStatement");
   AstNode* statement = NULL;
-  intptr_t label_pos = 0;
+  intptr_t label_pos = Scanner::kNoSourcePos;
   String* label_name = NULL;
   if (IsIdentifier()) {
     if (LookaheadToken(1) == Token::kCOLON) {
       // Statement starts with a label.
       label_name = CurrentLiteral();
       label_pos = TokenPos();
-      ASSERT(label_pos > 0);
+      ASSERT(label_pos >= 0);
       ConsumeToken();  // Consume identifier.
       ConsumeToken();  // Consume colon.
     }
@@ -10297,12 +10188,14 @@
 
 
 bool Parser::IsAwaitKeyword() {
-  return await_is_keyword_ && IsSymbol(Symbols::Await());
+  return (FLAG_await_is_keyword || await_is_keyword_) &&
+      IsSymbol(Symbols::Await());
 }
 
 
 bool Parser::IsYieldKeyword() {
-  return await_is_keyword_ && IsSymbol(Symbols::YieldKw());
+  return (FLAG_await_is_keyword || await_is_keyword_) &&
+      IsSymbol(Symbols::YieldKw());
 }
 
 
@@ -11810,6 +11703,7 @@
       ReportError(expr_pos, "expression is not assignable");
     }
     Token::Kind incr_op = CurrentToken();
+    const intptr_t op_pos = TokenPos();
     ConsumeToken();
     // Not prefix.
     LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
@@ -11817,17 +11711,17 @@
     Token::Kind binary_op =
         (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
     BinaryOpNode* add = new(Z) BinaryOpNode(
-        expr_pos,
+        op_pos,
         binary_op,
-        new(Z) LoadLocalNode(expr_pos, temp),
-        new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1))));
+        new(Z) LoadLocalNode(op_pos, temp),
+        new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1))));
     AstNode* store =
         CreateAssignmentNode(expr, add, expr_ident, expr_pos, true);
     ASSERT(store != NULL);
     // The result is a pair of the (side effects of the) store followed by
     // the (value of the) initial value temp variable load.
     let_expr->AddNode(store);
-    let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp));
+    let_expr->AddNode(new(Z) LoadLocalNode(op_pos, temp));
     return let_expr;
   }
   return expr;
@@ -12189,8 +12083,8 @@
     const Function& constructor,
     ArgumentListNode* arguments) {
   // Factories have one extra argument: the type arguments.
-  // Constructors have 2 extra arguments: rcvr and construction phase.
-  const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2;
+  // Constructors have 1 extra arguments: receiver.
+  const int kNumExtraArgs = 1;
   const int num_arguments = arguments->length() + kNumExtraArgs;
   const Array& arg_values =
       Array::Handle(Z, Array::New(num_arguments, Heap::kOld));
@@ -12205,7 +12099,6 @@
           TypeArguments::Handle(Z, type_arguments.Canonicalize()));
     }
     arg_values.SetAt(0, instance);
-    arg_values.SetAt(1, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Prepend type_arguments to list of arguments to factory.
     ASSERT(type_arguments.IsZoneHandle());
@@ -13437,8 +13330,7 @@
 
   // A constructor has an implicit 'this' parameter (instance to construct)
   // and a factory has an implicit 'this' parameter (type_arguments).
-  // A constructor has a second implicit 'phase' parameter.
-  intptr_t arguments_length = arguments->length() + 2;
+  intptr_t arguments_length = arguments->length() + 1;
 
   // An additional type check of the result of a redirecting factory may be
   // required.
@@ -13536,10 +13428,6 @@
       constructor_name = constructor.name();
       ASSERT(!constructor.IsNull());
     }
-    if (constructor.IsFactory()) {
-      // A factory does not have the implicit 'phase' parameter.
-      arguments_length -= 1;
-    }
   }
   ASSERT(!constructor.IsNull());
 
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 03333d5..1be0f50 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -484,7 +484,6 @@
       const Class& cls,
       intptr_t supercall_pos,
       LocalVariable* receiver,
-      AstNode* phase_parameter,
       ArgumentListNode* forwarding_args);
   StaticCallNode* ParseSuperInitializer(
       const Class& cls,
@@ -585,7 +584,6 @@
   void AddAsyncClosureVariables();
   void AddAsyncGeneratorVariables();
 
-  LocalVariable* LookupPhaseParameter();
   LocalVariable* LookupReceiver(LocalScope* from_scope, bool test_only);
   LocalVariable* LookupTypeArgumentsParameter(LocalScope* from_scope,
                                               bool test_only);
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 93d2107..97f90c3 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -229,7 +229,6 @@
     { "dart:core", "AbstractClassInstantiationError",
                    "AbstractClassInstantiationError._create" },
     { "dart:core", "ArgumentError", "ArgumentError." },
-    { "dart:core", "AssertionError", "AssertionError." },
     { "dart:core", "CyclicInitializationError",
                    "CyclicInitializationError." },
     { "dart:core", "FallThroughError", "FallThroughError._create" },
@@ -241,6 +240,7 @@
     { "dart:core", "RangeError", "RangeError.range" },
     { "dart:core", "StackOverflowError", "StackOverflowError." },
     { "dart:core", "UnsupportedError", "UnsupportedError." },
+    { "dart:core", "_AssertionError", "_AssertionError._create" },
     { "dart:core", "_CastError", "_CastError._create" },
     { "dart:core", "_InternalError", "_InternalError." },
     { "dart:core", "_InvocationMirror", "_allocateInvocationMirror" },
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 1aba7d3..17a8a73 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -1390,6 +1390,11 @@
     GrowableArray<Function*> inlined_functions;
     if (!code.IsNull()) {
       intptr_t offset = pc - code.EntryPoint();
+      if (frame_index != 0) {
+        // The PC of frames below the top frame is a call's return address,
+        // which can belong to a different inlining interval than the call.
+        offset--;
+      }
       code.GetInlinedFunctionsAt(offset, &inlined_functions);
     }
     if (code.IsNull() || (inlined_functions.length() == 0)) {
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 3533851..63ac759 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -34,6 +34,22 @@
 };
 
 
+class DisableBackgroundCompilationScope : public ValueObject {
+ public:
+  DisableBackgroundCompilationScope()
+      : FLAG_background_compilation_(FLAG_background_compilation) {
+    FLAG_background_compilation = false;
+  }
+
+  ~DisableBackgroundCompilationScope() {
+    FLAG_background_compilation = FLAG_background_compilation_;
+  }
+
+ private:
+  const bool FLAG_background_compilation_;
+};
+
+
 // Temporarily adjust the maximum profile depth.
 class MaxProfileDepthScope : public ValueObject {
  public:
@@ -139,6 +155,7 @@
   delete sample_buffer;
 }
 
+
 static RawClass* GetClass(const Library& lib, const char* name) {
   const Class& cls = Class::Handle(
       lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name))));
@@ -147,6 +164,14 @@
 }
 
 
+static RawFunction* GetFunction(const Library& lib, const char* name) {
+  const Function& func = Function::Handle(
+      lib.LookupFunctionAllowPrivate(String::Handle(Symbols::New(name))));
+  EXPECT(!func.IsNull());  // No ambiguity error expected.
+  return func.raw();
+}
+
+
 class AllocationFilter : public SampleFilter {
  public:
   AllocationFilter(Isolate* isolate,
@@ -1154,6 +1179,8 @@
 
 TEST_CASE(Profiler_FunctionInline) {
   DisableNativeProfileScope dnps;
+  DisableBackgroundCompilationScope dbcs;
+
   const char* kScript =
       "class A {\n"
       "  var a;\n"
@@ -1180,8 +1207,6 @@
       "  B.boo(true);\n"
       "}\n";
 
-  const bool old_flag = FLAG_background_compilation;
-  FLAG_background_compilation = false;
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& root_library = Library::Handle();
@@ -1398,7 +1423,133 @@
     EXPECT_STREQ("[Inline End]", walker.CurrentName());
     EXPECT(!walker.Down());
   }
-  FLAG_background_compilation = old_flag;
+}
+
+
+TEST_CASE(Profiler_InliningIntervalBoundry) {
+  // The PC of frames below the top frame is a call's return address,
+  // which can belong to a different inlining interval than the call.
+  // This test checks the profiler service takes this into account; see
+  // ProfileBuilder::ProcessFrame.
+
+  DisableNativeProfileScope dnps;
+  DisableBackgroundCompilationScope dbcs;
+  const char* kScript =
+      "class A {\n"
+      "}\n"
+      "bool alloc = false;"
+      "maybeAlloc() {\n"
+      "  try {\n"
+      "    if (alloc) new A();\n"
+      "  } catch (e) {\n"
+      "  }\n"
+      "}\n"
+      "right() => maybeAlloc();\n"
+      "doNothing() {\n"
+      "  try {\n"
+      "  } catch (e) {\n"
+      "  }\n"
+      "}\n"
+      "wrong() => doNothing();\n"
+      "a() {\n"
+      "  try {\n"
+      "    right();\n"
+      "    wrong();\n"
+      "  } catch (e) {\n"
+      "  }\n"
+      "}\n"
+      "mainNoAlloc() {\n"
+      "  for (var i = 0; i < 20000; i++) {\n"
+      "    a();\n"
+      "  }\n"
+      "}\n"
+      "mainAlloc() {\n"
+      "  alloc = true;\n"
+      "  a();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  Library& root_library = Library::Handle();
+  root_library ^= Api::UnwrapHandle(lib);
+
+  const Class& class_a = Class::Handle(GetClass(root_library, "A"));
+  EXPECT(!class_a.IsNull());
+
+  // Compile and optimize.
+  Dart_Handle result = Dart_Invoke(lib, NewString("mainNoAlloc"), 0, NULL);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
+  EXPECT_VALID(result);
+
+  // At this point a should be optimized and have inlined both right and wrong,
+  // but not maybeAllocate or doNothing.
+  Function& func = Function::Handle();
+  func = GetFunction(root_library, "a");
+  EXPECT(!func.is_inlinable());
+  EXPECT(func.HasOptimizedCode());
+  func = GetFunction(root_library, "right");
+  EXPECT(func.is_inlinable());
+  func = GetFunction(root_library, "wrong");
+  EXPECT(func.is_inlinable());
+  func = GetFunction(root_library, "doNothing");
+  EXPECT(!func.is_inlinable());
+  func = GetFunction(root_library, "maybeAlloc");
+  EXPECT(!func.is_inlinable());
+
+  {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(thread, &filter, Profile::kNoTags);
+    // We should have no allocation samples.
+    EXPECT_EQ(0, profile.sample_count());
+  }
+
+  // Turn on allocation tracing for A.
+  class_a.SetTraceAllocation(true);
+
+  result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
+  EXPECT_VALID(result);
+
+  {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(thread, &filter, Profile::kNoTags);
+    EXPECT_EQ(1, profile.sample_count());
+    ProfileTrieWalker walker(&profile);
+
+    // Inline expansion should show us the complete call chain:
+    walker.Reset(Profile::kExclusiveFunction);
+    EXPECT(walker.Down());
+    EXPECT_STREQ("maybeAlloc", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("right", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("a", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("mainAlloc", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Inline expansion should show us the complete call chain:
+    walker.Reset(Profile::kInclusiveFunction);
+    EXPECT(walker.Down());
+    EXPECT_STREQ("mainAlloc", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("a", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("right", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("maybeAlloc", walker.CurrentName());
+    EXPECT(!walker.Down());
+  }
 }
 
 
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index 626d940..5b1605a 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -52,14 +52,14 @@
     // We cache the Dart stack pointer and the stack limit in callee-saved
     // registers, then align and call, restoring CSP and SP on return from the
     // call.
-    __ mov(R25, CSP);
-    __ mov(R26, SP);
+    __ mov(R24, CSP);
+    __ mov(R25, SP);
     __ ReserveAlignedFrameSpace(0);
     __ mov(CSP, SP);
     __ ldr(TMP, Address(THR, Thread::OffsetFromThread(this)));
     __ blr(TMP);
-    __ mov(SP, R26);
-    __ mov(CSP, R25);
+    __ mov(SP, R25);
+    __ mov(CSP, R24);
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 7558a1d..7a81040 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -45,7 +45,11 @@
   };
 
   // Dummy token index reflecting an unknown source position.
-  static const intptr_t kNoSourcePos = 0;
+  static const intptr_t kNoSourcePos = -1;
+
+  static bool ValidSourcePosition(intptr_t token_pos) {
+    return (token_pos >= 0) || (token_pos == kNoSourcePos);
+  }
 
   typedef ZoneGrowableArray<TokenDescriptor> GrowableTokenStream;
 
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index d325b5b..4c52227 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -29,8 +29,8 @@
       loop_level_(loop_level),
       context_level_(LocalScope::kUnitializedContextLevel),
       num_context_variables_(0),
-      begin_token_pos_(0),
-      end_token_pos_(0),
+      begin_token_pos_(Scanner::kNoSourcePos),
+      end_token_pos_(Scanner::kNoSourcePos),
       variables_(),
       labels_(),
       referenced_() {
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 4735b51..631a4ec 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -30,6 +30,7 @@
 #include "vm/reusable_handles.h"
 #include "vm/service_event.h"
 #include "vm/service_isolate.h"
+#include "vm/source_report.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 #include "vm/unicode.h"
@@ -561,6 +562,125 @@
 }
 
 
+class EnumListParameter : public MethodParameter {
+ public:
+  EnumListParameter(const char* name, bool required, const char* const* enums)
+      : MethodParameter(name, required),
+        enums_(enums) {
+  }
+
+  virtual bool Validate(const char* value) const {
+    return ElementCount(value) >= 0;
+  }
+
+  const char** Parse(Zone* zone, const char* value_in) const {
+    const char* kJsonChars = " \t\r\n[,]";
+
+    // Make a writeable copy of the value.
+    char* value = zone->MakeCopyOfString(value_in);
+    intptr_t element_count = ElementCount(value);
+    intptr_t element_pos = 0;
+
+    // Allocate our element array.  +1 for NULL terminator.
+    char** elements = zone->Alloc<char*>(element_count + 1);
+    elements[element_count] = NULL;
+
+    // Parse the string destructively.  Build the list of elements.
+    while (element_pos < element_count) {
+      // Skip to the next element.
+      value += strspn(value, kJsonChars);
+
+      intptr_t len = strcspn(value, kJsonChars);
+      ASSERT(len > 0);  // We rely on the parameter being validated already.
+      value[len] = '\0';
+      elements[element_pos++] = value;
+
+      // Advance.  +1 for null terminator.
+      value += (len + 1);
+    }
+    return const_cast<const char**>(elements);
+  }
+
+ private:
+  // For now observatory enums are ascii letters plus underscore.
+  static bool IsEnumChar(char c) {
+    return (((c >= 'a') && (c <= 'z')) ||
+            ((c >= 'A') && (c <= 'Z')) ||
+            (c == '_'));
+  }
+
+  // Returns number of elements in the list.  -1 on parse error.
+  intptr_t ElementCount(const char* value) const {
+    const char* kJsonWhitespaceChars = " \t\r\n";
+
+    if (value == NULL) {
+      return -1;
+    }
+    const char* cp = value;
+    cp += strspn(cp, kJsonWhitespaceChars);
+    if (*cp++ != '[') {
+      // Missing initial [.
+      return -1;
+    }
+    bool closed = false;
+    bool element_allowed = true;
+    intptr_t element_count = 0;
+    while (true) {
+      // Skip json whitespace.
+      cp += strspn(cp, kJsonWhitespaceChars);
+      switch (*cp) {
+        case '\0':
+          return closed ? element_count : -1;
+        case ']':
+          closed = true;
+          cp++;
+          break;
+        case ',':
+          if (element_allowed) {
+            return -1;
+          }
+          element_allowed = true;
+          cp++;
+          break;
+        default:
+          if (!element_allowed) {
+            return -1;
+          }
+          bool valid_enum = false;
+          if (enums_ != NULL) {
+            for (intptr_t i = 0; enums_[i] != NULL; i++) {
+              intptr_t len = strlen(enums_[i]);
+              if (strncmp(cp, enums_[i], len) == 0) {
+                element_count++;
+                valid_enum = true;
+                cp += len;
+                element_allowed = false;  // we need a comma first.
+                break;
+              }
+            }
+          } else {
+            // Allow any identifiers
+            const char* id_start = cp;
+            while (IsEnumChar(*cp)) {
+              cp++;
+            }
+            if (cp == id_start) {
+              // Empty identifier, something like this [,].
+              return -1;
+            }
+          }
+          if (!valid_enum) {
+            return -1;
+          }
+          break;
+      }
+    }
+  }
+
+  const char* const* enums_;
+};
+
+
 typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js);
 
 
@@ -2191,6 +2311,86 @@
 }
 
 
+static const char* kCallSitesStr = "CallSites";
+static const char* kCoverageStr = "Coverage";
+
+
+static const char* const report_enum_names[] = {
+  kCallSitesStr,
+  kCoverageStr,
+  NULL,
+};
+
+
+static const EnumListParameter* reports_parameter =
+    new EnumListParameter("reports", true, report_enum_names);
+
+
+static const MethodParameter* get_source_report_params[] = {
+  ISOLATE_PARAMETER,
+  reports_parameter,
+  new IdParameter("scriptId", false),
+  new UIntParameter("tokenPos", false),
+  new UIntParameter("endTokenPos", false),
+  new BoolParameter("forceCompile", false),
+  NULL,
+};
+
+
+static bool GetSourceReport(Thread* thread, JSONStream* js) {
+  const char* reports_str = js->LookupParam("reports");
+  const char** reports = reports_parameter->Parse(thread->zone(), reports_str);
+  intptr_t report_set = 0;
+  while (*reports != NULL) {
+    if (strcmp(*reports, kCallSitesStr) == 0) {
+      report_set |= SourceReport::kCallSites;
+    } else if (strcmp(*reports, kCoverageStr) == 0) {
+      report_set |= SourceReport::kCoverage;
+    }
+    reports++;
+  }
+
+  SourceReport::CompileMode compile_mode = SourceReport::kNoCompile;
+  if (BoolParameter::Parse(js->LookupParam("forceCompile"), false)) {
+    compile_mode = SourceReport::kForceCompile;
+  }
+
+  Script& script = Script::Handle();
+  intptr_t start_pos = UIntParameter::Parse(js->LookupParam("tokenPos"));
+  intptr_t end_pos = UIntParameter::Parse(js->LookupParam("endTokenPos"));
+
+  if (js->HasParam("scriptId")) {
+    // Get the target script.
+    const char* script_id_param = js->LookupParam("scriptId");
+    const Object& obj =
+        Object::Handle(LookupHeapObject(thread, script_id_param, NULL));
+    if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) {
+      PrintInvalidParamError(js, "scriptId");
+      return true;
+    }
+    script ^= obj.raw();
+  } else {
+    if (js->HasParam("tokenPos")) {
+      js->PrintError(
+          kInvalidParams,
+          "%s: the 'tokenPos' parameter requires the 'scriptId' parameter",
+          js->method());
+      return true;
+    }
+    if (js->HasParam("endTokenPos")) {
+      js->PrintError(
+          kInvalidParams,
+          "%s: the 'endTokenPos' parameter requires the 'scriptId' parameter",
+          js->method());
+      return true;
+    }
+  }
+  SourceReport report(report_set, compile_mode);
+  report.PrintJSON(js, script, start_pos, end_pos);
+  return true;
+}
+
+
 static const MethodParameter* get_call_site_data_params[] = {
   ISOLATE_PARAMETER,
   new IdParameter("targetId", false),
@@ -3608,6 +3808,8 @@
     get_retained_size_params },
   { "_getRetainingPath", GetRetainingPath,
     get_retaining_path_params },
+  { "_getSourceReport", GetSourceReport,
+    get_source_report_params },
   { "getStack", GetStack,
     get_stack_params },
   { "_getTagProfile", GetTagProfile,
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 923f6d4..a316c6c 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -344,6 +344,7 @@
     ASSERT(ServiceIsolate::IsServiceIsolate(I));
     ServiceIsolate::SetServiceIsolate(NULL);
     ServiceIsolate::SetServicePort(ILLEGAL_PORT);
+    I->WaitForOutstandingSpawns();
     {
       // Print the error if there is one.  This may execute dart code to
       // print the exception object, so we need to use a StartIsolateScope.
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index f3e6514..b65ae80 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -1171,6 +1171,16 @@
 }
 
 
+uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
+                                          uint32_t compare_value,
+                                          uint32_t new_value) {
+  COMPILE_ASSERT(sizeof(uword) == sizeof(uint32_t));
+  return CompareExchange(reinterpret_cast<uword*>(address),
+                         static_cast<uword>(compare_value),
+                         static_cast<uword>(new_value));
+}
+
+
 // Returns the top of the stack area to enable checking for stack pointer
 // validity.
 uword Simulator::StackTop() const {
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 3976c0c..af3cb09 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -107,6 +107,9 @@
   static uword CompareExchange(uword* address,
                                uword compare_value,
                                uword new_value);
+  static uint32_t CompareExchangeUint32(uint32_t* address,
+                                        uint32_t compare_value,
+                                        uint32_t new_value);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 0f1ed56..e0df115 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -1253,6 +1253,26 @@
 }
 
 
+uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
+                                          uint32_t compare_value,
+                                          uint32_t new_value) {
+  MutexLocker ml(exclusive_access_lock_);
+  // We do not get a reservation as it would be guaranteed to be found when
+  // writing below. No other thread is able to make a reservation while we
+  // hold the lock.
+  uint32_t value = *address;
+  if (value == compare_value) {
+    *address = new_value;
+    // Same effect on exclusive access state as a successful STREX.
+    HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
+  } else {
+    // Same effect on exclusive access state as an LDREX.
+    SetExclusiveAccess(reinterpret_cast<uword>(address));
+  }
+  return value;
+}
+
+
 // Unsupported instructions use Format to print an error and stop execution.
 void Simulator::Format(Instr* instr, const char* format) {
   OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n",
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h
index d23e83b..d395f6b 100644
--- a/runtime/vm/simulator_arm64.h
+++ b/runtime/vm/simulator_arm64.h
@@ -102,6 +102,9 @@
   static uword CompareExchange(uword* address,
                                uword compare_value,
                                uword new_value);
+  static uint32_t CompareExchangeUint32(uint32_t* address,
+                                        uint32_t compare_value,
+                                        uint32_t new_value);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index 5fabae7..f8007ed 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1191,6 +1191,16 @@
 }
 
 
+uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
+                                          uint32_t compare_value,
+                                          uint32_t new_value) {
+  COMPILE_ASSERT(sizeof(uword) == sizeof(uint32_t));
+  return CompareExchange(reinterpret_cast<uword*>(address),
+                         static_cast<uword>(compare_value),
+                         static_cast<uword>(new_value));
+}
+
+
 // Calls into the Dart runtime are based on this interface.
 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
 
diff --git a/runtime/vm/simulator_mips.h b/runtime/vm/simulator_mips.h
index b4807bf..8d10c3f 100644
--- a/runtime/vm/simulator_mips.h
+++ b/runtime/vm/simulator_mips.h
@@ -121,6 +121,9 @@
   static uword CompareExchange(uword* address,
                                uword compare_value,
                                uword new_value);
+  static uint32_t CompareExchangeUint32(uint32_t* address,
+                                        uint32_t compare_value,
+                                        uint32_t new_value);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 242957b..8c08726 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -10,8 +10,8 @@
 
 namespace dart {
 
-SourceReport::SourceReport(ReportKind report_kind, CompileMode compile_mode)
-    : report_kind_(report_kind),
+SourceReport::SourceReport(intptr_t report_set, CompileMode compile_mode)
+    : report_set_(report_set),
       compile_mode_(compile_mode),
       thread_(NULL),
       script_(NULL),
@@ -35,6 +35,11 @@
 }
 
 
+bool SourceReport::IsReportRequested(ReportKind report_kind) {
+  return (report_set_ & report_kind) != 0;
+}
+
+
 bool SourceReport::ShouldSkipFunction(const Function& func) {
   if (script_ != NULL && !script_->IsNull()) {
     if (func.script() != script_->raw()) {
@@ -239,15 +244,25 @@
   }
   ASSERT(!code.IsNull());
 
+  // We skip compiled async functions.  Once an async function has
+  // been compiled, there is another function with the same range which
+  // actually contains the user code.
+  if (func.IsAsyncFunction() ||
+      func.IsAsyncGenerator() ||
+      func.IsSyncGenerator()) {
+    return;
+  }
+
   JSONObject range(jsarr);
   range.AddProperty("scriptIndex", GetScriptIndex(script));
   range.AddProperty("startPos", begin_pos);
   range.AddProperty("endPos", end_pos);
   range.AddProperty("compiled", true);
 
-  if (report_kind_ == kCallSites) {
+  if (IsReportRequested(kCallSites)) {
     PrintCallSitesData(&range, func, code);
-  } else if (report_kind_ == kCoverage) {
+  }
+  if (IsReportRequested(kCoverage)) {
     PrintCoverageData(&range, func, code);
   }
 }
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 69529d3..09c8092 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -18,8 +18,8 @@
 class SourceReport {
  public:
   enum ReportKind {
-    kCallSites,
-    kCoverage,
+    kCallSites = 0x1,
+    kCoverage  = 0x2,
   };
 
   enum CompileMode {
@@ -27,7 +27,9 @@
     kForceCompile
   };
 
-  explicit SourceReport(ReportKind report_kind,
+  // report_set is a bitvector indicating which reports to generate
+  // (e.g. kCallSites | kCoverage).
+  explicit SourceReport(intptr_t report_set,
                         CompileMode compile = kNoCompile);
 
   // Generate a source report for (some subrange of) a script.
@@ -44,6 +46,7 @@
   Thread* thread() const { return thread_; }
   Zone* zone() const { return thread_->zone(); }
 
+  bool IsReportRequested(ReportKind report_kind);
   bool ShouldSkipFunction(const Function& func);
   intptr_t GetScriptIndex(const Script& script);
   bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib);
@@ -90,7 +93,7 @@
     }
   };
 
-  ReportKind report_kind_;
+  intptr_t report_set_;
   CompileMode compile_mode_;
   Thread* thread_;
   const Script* script_;
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index 075ac36..0e1bb79 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -409,4 +409,53 @@
       buffer);
 }
 
+
+TEST_CASE(SourceReport_MultipleReports) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  helper0();\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCallSites|SourceReport::kCoverage);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with no callsites (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"callSites\":[],"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range not compiled (helper1).
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
+
+      // One range compiled with one callsite (main).
+      "{\"scriptIndex\":0,\"startPos\":12,\"endPos\":22,\"compiled\":true,"
+      "\"callSites\":["
+      "{\"name\":\"helper0\",\"tokenPos\":17,\"cacheEntries\":["
+      "{\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"helper0\",\"owner\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"test-lib\"},"
+      "\"_kind\":\"RegularFunction\",\"static\":true,\"const\":false,"
+      "\"_intrinsic\":false,\"_native\":false},\"count\":1}]}],"
+      "\"coverage\":{\"hits\":[17],\"misses\":[]}}],"
+
+      // One script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index a48be15..a1ca2eb 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -44,8 +44,8 @@
 static const int kSavedAboveReturnAddress = 3;  // Saved above return address.
 
 // Entry and exit frame layout.
-static const int kExitLinkSlotFromEntryFp = -21;
-COMPILE_ASSERT(kAbiPreservedCpuRegCount == 9);
+static const int kExitLinkSlotFromEntryFp = -22;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 10);
 COMPILE_ASSERT(kAbiPreservedFpuRegCount == 8);
 
 }  // namespace dart
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index e991fdb..ad3c995 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -45,9 +45,13 @@
 
 
 void StubCode::InitOnce() {
+#if !defined(DART_PRECOMPILED)
   // Generate all the stubs.
   Code& code = Code::Handle();
   VM_STUB_CODE_LIST(STUB_CODE_GENERATE);
+#else
+  UNREACHABLE();
+#endif  // DART_PRECOMPILED
 }
 
 
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 7624fa2..0585653 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -101,7 +101,7 @@
   // We are entering runtime code, so the C stack pointer must be restored from
   // the stack limit to the top of the stack. We cache the stack limit address
   // in a callee-saved register.
-  __ mov(R26, CSP);
+  __ mov(R25, CSP);
   __ mov(CSP, SP);
 
   __ blr(R5);
@@ -109,7 +109,7 @@
 
   // Restore SP and CSP.
   __ mov(SP, CSP);
-  __ mov(CSP, R26);
+  __ mov(CSP, R25);
 
   // Retval is next to 1st argument.
   // Mark that the thread is executing Dart code.
@@ -204,7 +204,7 @@
   // We are entering runtime code, so the C stack pointer must be restored from
   // the stack limit to the top of the stack. We cache the stack limit address
   // in the Dart SP register, which is callee-saved in the C ABI.
-  __ mov(R26, CSP);
+  __ mov(R25, CSP);
   __ mov(CSP, SP);
 
   __ mov(R1, R5);  // Pass the function entrypoint to call.
@@ -215,7 +215,7 @@
 
   // Restore SP and CSP.
   __ mov(SP, CSP);
-  __ mov(CSP, R26);
+  __ mov(CSP, R25);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -297,7 +297,7 @@
   // We are entering runtime code, so the C stack pointer must be restored from
   // the stack limit to the top of the stack. We cache the stack limit address
   // in the Dart SP register, which is callee-saved in the C ABI.
-  __ mov(R26, CSP);
+  __ mov(R25, CSP);
   __ mov(CSP, SP);
 
   // Call native function or redirection via simulator.
@@ -305,7 +305,7 @@
 
   // Restore SP and CSP.
   __ mov(SP, CSP);
-  __ mov(CSP, R26);
+  __ mov(CSP, R25);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -829,7 +829,7 @@
   __ LoadFromOffset(R6, THR, Thread::top_exit_frame_info_offset());
   __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -21);
+  ASSERT(kExitLinkSlotFromEntryFp == -22);
   __ Push(R6);
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 310660d..1c40fb5 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -57,7 +57,6 @@
   V(AnonymousClosure, "<anonymous closure>")                                   \
   V(ImplicitClosure, "<implicit closure>")                                     \
   V(ClosureParameter, ":closure")                                              \
-  V(PhaseParameter, ":phase")                                                  \
   V(TypeArgumentsParameter, ":type_arguments")                                 \
   V(AssertionError, "_AssertionError")                                         \
   V(CastError, "_CastError")                                                   \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 2357ce6..c220913 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -295,6 +295,16 @@
 }
 
 
+bool Thread::CanCollectGarbage() const {
+  // We have non mutator threads grow the heap instead of triggering
+  // a garbage collection when they are at a safepoint (e.g: background
+  // compiler thread finalizing and installing code at a safepoint).
+  // Note: This code will change once the new Safepoint logic is in place.
+  return (IsMutatorThread() ||
+          (isolate_ != NULL && !isolate_->thread_registry()->AtSafepoint()));
+}
+
+
 bool Thread::IsExecutingDartCode() const {
   return (top_exit_frame_info() == 0) &&
          (vm_tag() == VMTag::kDartTagId);
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index f85be7b..ad073af 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -164,6 +164,7 @@
     return OFFSET_OF(Thread, isolate_);
   }
   bool IsMutatorThread() const;
+  bool CanCollectGarbage() const;
 
   // Is |this| executing Dart code?
   bool IsExecutingDartCode() const;
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 9694527..2861fab 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -200,7 +200,7 @@
 void AssemblerTest::Assemble() {
   const String& function_name = String::ZoneHandle(Symbols::New(name_));
   const Class& cls = Class::ZoneHandle(
-      Class::New(function_name, Script::Handle(), Scanner::kNoSourcePos));
+      Class::New(function_name, Script::Handle(), 0));
   const Library& lib = Library::ZoneHandle(Library::New(function_name));
   cls.set_library(lib);
   Function& function = Function::ZoneHandle(
@@ -220,7 +220,7 @@
 
 CodeGenTest::CodeGenTest(const char* name)
   : function_(Function::ZoneHandle()),
-    node_sequence_(new SequenceNode(Scanner::kNoSourcePos,
+    node_sequence_(new SequenceNode(0,
                                     new LocalScope(NULL, 0, 0))),
     default_parameter_values_(new ZoneGrowableArray<const Instance*> ()) {
   ASSERT(name != NULL);
@@ -228,7 +228,7 @@
   // Add function to a class and that class to the class dictionary so that
   // frame walking can be used.
   const Class& cls = Class::ZoneHandle(
-       Class::New(function_name, Script::Handle(), Scanner::kNoSourcePos));
+       Class::New(function_name, Script::Handle(), 0));
   function_ = Function::New(
       function_name, RawFunction::kRegularFunction,
       true, false, false, false, false, cls, 0);
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 67b23f1..aa1ee40 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -174,6 +174,7 @@
     'flow_graph_allocator.h',
     'flow_graph_builder.cc',
     'flow_graph_builder.h',
+    'flow_graph_builder_test.cc',
     'flow_graph_compiler.cc',
     'flow_graph_compiler.h',
     'flow_graph_compiler_arm.cc',
diff --git a/samples/third_party/dromaeo/.gitignore b/samples/third_party/dromaeo/.gitignore
deleted file mode 100644
index 378eac2..0000000
--- a/samples/third_party/dromaeo/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/samples/third_party/dromaeo/lib/transformer.dart b/samples/third_party/dromaeo/lib/transformer.dart
deleted file mode 100644
index fa50ea3..0000000
--- a/samples/third_party/dromaeo/lib/transformer.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-library dromaeo.transformer;
-
-import 'dart:async';
-import 'package:barback/barback.dart';
-
-/// Transformer used by `pub build` and `pub serve` to rewrite dromaeo html
-/// files to run performance tests.
-class DromaeoTransformer extends Transformer {
-
-  final BarbackSettings settings;
-
-  DromaeoTransformer.asPlugin(this.settings);
-
-  /// The index.html file and the tests/dom-*-html.html files are the ones we
-  /// apply this transform to.
-  Future<bool> isPrimary(AssetId id) {
-    var reg = new RegExp('(tests/dom-.+-html\.html\$)|(index\.html\$)');
-    return new Future.value(reg.hasMatch(id.path));
-  }
-
-  Future apply(Transform transform) {
-    Asset primaryAsset = transform.primaryInput;
-    AssetId primaryAssetId = primaryAsset.id;
-
-    return primaryAsset.readAsString().then((String fileContents) {
-      var filename = primaryAssetId.toString();
-      var outputFileContents = fileContents;
-
-      if (filename.endsWith('index.html')) {
-        var index = outputFileContents.indexOf(
-            '<script src="packages/browser/dart.js">');
-        outputFileContents = outputFileContents.substring(0, index) +
-            '<script src="packages/browser_controller' +
-            '/perf_test_controller.js"></script>\n' +
-            outputFileContents.substring(index);
-        transform.addOutput(new Asset.fromString(new AssetId.parse(
-            primaryAssetId.toString().replaceAll('.html', '-dart.html')),
-            outputFileContents));
-      }
-
-      outputFileContents = _sourceJsNotDart(outputFileContents);
-      // Rename the script to take the JavaScript source.
-      transform.addOutput(new Asset.fromString(new AssetId.parse(
-          _appendJs(primaryAssetId.toString())),
-          outputFileContents));
-    });
-  }
-
-  String _appendJs(String path) => path.replaceAll('.html', '-js.html');
-
-  /// Given an html file that sources a Dart file, rewrite the html to instead
-  /// source the compiled JavaScript file.
-  String _sourceJsNotDart(String fileContents) {
-    var dartScript = new RegExp(
-        '<script type="application/dart" src="([\\w-]+)\.dart">');
-    var match = dartScript.firstMatch(fileContents);
-    return fileContents.replaceAll(dartScript, '<script type="text/javascript"'
-        ' src="${match.group(1)+ ".dart.js"}" defer>');
-  }
-}
diff --git a/samples/third_party/dromaeo/pubspec.yaml b/samples/third_party/dromaeo/pubspec.yaml
deleted file mode 100644
index 955919d..0000000
--- a/samples/third_party/dromaeo/pubspec.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: dromaeo
-version: 0.00.1-dev
-authors: ["Dart Team <misc@dartlang.org>"]
-homepage: http://www.dartlang.org
-description: >
- Dromaeo test suite, written in Dart.
-dependencies:
-  browser_controller: ">=0.00.1-dev <0.0.2"
-  barback: ">=0.13.0 <0.14.0"
-  browser: ">=0.10.0 <0.10.1"
-environment:
-  sdk: any
-transformers:
-- dromaeo
-- $dart2js:
-    checked: false
-    minify: true #TODO: How do you minify for Dart, too? The docs say you indent two spaces less...
diff --git a/samples/third_party/dromaeo/web/Dromaeo.dart b/samples/third_party/dromaeo/web/Dromaeo.dart
deleted file mode 100644
index bf0e116..0000000
--- a/samples/third_party/dromaeo/web/Dromaeo.dart
+++ /dev/null
@@ -1,243 +0,0 @@
-library dromaeo_test;
-
-import 'dart:html';
-import 'dart:async';
-import "dart:convert";
-import 'dart:math' as Math;
-import 'dart:js' as js;
-import 'Suites.dart';
-
-main() {
-  new Dromaeo().run();
-}
-
-class SuiteController {
-  final SuiteDescription _suiteDescription;
-  final IFrameElement _suiteIframe;
-
-  DivElement _element;
-  double _meanProduct;
-  int _nTests;
-
-  SuiteController(this._suiteDescription, this._suiteIframe)
-      : _meanProduct = 1.0,
-        _nTests = 0 {
-    _make();
-    _init();
-  }
-
-  start() {
-    _suiteIframe.contentWindow.postMessage('start', '*');
-  }
-
-  update(String testName, num mean, num error, double percent) {
-    _meanProduct *= mean;
-    _nTests++;
-
-    final meanAsString = mean.toStringAsFixed(2);
-    final errorAsString = error.toStringAsFixed(2);
-    final Element progressDisplay = _element.nextNode.nextNode;
-    progressDisplay.innerHtml =
-        '${progressDisplay.innerHtml}<li><b>${testName}:</b>'
-        '${meanAsString}<small> runs/s &#177;${errorAsString}%<small></li>';
-    _updateTestPos(percent);
-  }
-
-  _make() {
-    _element = _createDiv('test');
-    // TODO(antonm): add an onclick functionality.
-    _updateTestPos();
-  }
-
-  _updateTestPos([double percent = 1.0]) {
-    String suiteName = _suiteDescription.name;
-    final done = percent >= 100.0;
-    String info = '';
-    if (done) {
-      final parent = _element.parent;
-      parent.attributes['class'] = '${parent.attributes["class"]} done';
-      final mean = Math.pow(_meanProduct, 1.0 / _nTests).toStringAsFixed(2);
-      info = '<span>${mean} runs/s</span>';
-    }
-    _element.innerHtml =
-        '<b>${suiteName}:</b>'
-        '<div class="bar"><div style="width:${percent}%;">${info}</div></div>';
-  }
-
-  _init() {
-    final div = _createDiv('result-item');
-    div.nodes.add(_element);
-    final description = _suiteDescription.description;
-    final originUrl = _suiteDescription.origin.url;
-    final testUrl = '${_suiteDescription.file}';
-    div.innerHtml =
-        '${div.innerHtml}<p>${description}<br/><a href="${originUrl}">Origin</a'
-        '>, <a href="${testUrl}">Source</a>'
-        '<ol class="results"></ol>';
-    // Reread the element, as the previous wrapper get disconnected thanks
-    // to .innerHtml update above.
-    _element = div.nodes[0];
-
-    document.querySelector('#main').nodes.add(div);
-  }
-
-  DivElement _createDiv(String clazz) {
-    final div = new DivElement();
-    div.attributes['class'] = clazz;
-    return div;
-  }
-}
-
-class Dromaeo {
-  final List<SuiteController> _suiteControllers;
-  Function _handler;
-
-  Dromaeo()
-      : _suiteControllers = new List<SuiteController>()
-  {
-    _handler = _createHandler();
-    window.onMessage.listen(
-        (MessageEvent event) {
-          try {
-            final response = JSON.decode(event.data);
-            _handler = _handler(response['command'], response['data']);
-          } catch (e, stacktrace) {
-            if (!(e is FormatException &&
-                (event.data.toString().startsWith('unittest') ||
-                event.data.toString().startsWith('dart')))) {
-              // Hack because unittest also uses post messages to communicate.
-              // So the fact that the event.data is not proper json is not
-              // always an error.
-              print('Exception: ${e}: ${stacktrace}');
-              print(event.data);
-            }
-          }
-        });
-  }
-
-  run() {
-    // TODO(vsm): Initial page should not run.  For now, run all
-    // tests by default.
-    var tags = window.location.search;
-    if (tags.length > 1) {
-      tags = tags.substring(1);
-    } else if (window.navigator.userAgent.contains('(Dart)')) {
-      // TODO(vsm): Update when we change Dart VM detection.
-      tags = 'js|dart&html';
-    } else {
-      tags = 'js|dart2js&html';
-    }
-
-    // TODO(antonm): create Re-run tests href.
-    final Element suiteNameElement = _byId('overview').nodes[0];
-    final category = Suites.getCategory(tags);
-    if (category != null) {
-      suiteNameElement.innerHtml = category;
-    }
-    _css(_byId('tests'), 'display', 'none');
-    for (SuiteDescription suite in Suites.getSuites(tags)) {
-      final iframe = new IFrameElement();
-      _css(iframe, 'height', '1px');
-      _css(iframe, 'width', '1px');
-      iframe.src = '${suite.file}';
-      document.body.nodes.add(iframe);
-
-      _suiteControllers.add(new SuiteController(suite, iframe));
-    }
-  }
-
-  static const double _SECS_PER_TEST = 5.0;
-
-  Function _createHandler() {
-    int suitesLoaded = 0;
-    int totalTests = 0;
-    int currentSuite;
-    double totalTimeSecs, estimatedTimeSecs;
-
-    // TODO(jat): Remove void type below. Bug 5269037.
-    void _updateTime() {
-      final mins = (estimatedTimeSecs / 60).floor();
-      final secs = (estimatedTimeSecs - mins * 60).round();
-      final secsAsString = '${(secs < 10 ? "0" : "")}$secs';
-      _byId('left').innerHtml = '${mins}:${secsAsString}';
-
-      final elapsed = totalTimeSecs - estimatedTimeSecs;
-      final percent = (100 * elapsed / totalTimeSecs).toStringAsFixed(2);
-      _css(_byId('timebar'), 'width', '${percent}%');
-    }
-
-    Function loading, running, done;
-
-    loading = (String command, var data) {
-      assert(command == 'inited');
-      suitesLoaded++;
-      totalTests += data['nTests'];
-      if (suitesLoaded == _suitesTotal) {
-        totalTimeSecs = estimatedTimeSecs = _SECS_PER_TEST * totalTests;
-        _updateTime();
-        currentSuite = 0;
-        _suiteControllers[currentSuite].start();
-        return running;
-      }
-
-      return loading;
-    };
-
-    running = (String command, var data) {
-      switch (command) {
-        case 'result':
-          final testName = data['testName'];
-          final mean = data['mean'];
-          final error = data['error'];
-          final percent = data['percent'];
-          _suiteControllers[currentSuite].update(testName, mean, error, percent);
-          estimatedTimeSecs -= _SECS_PER_TEST;
-          _updateTime();
-          return running;
-
-        case 'over':
-          currentSuite++;
-          if (currentSuite < _suitesTotal) {
-            _suiteControllers[currentSuite].start();
-            return running;
-          }
-          document.body.attributes['class'] = 'alldone';
-
-          var report = js.context['reportPerformanceTestDone'];
-          if (report != null) {
-            report.apply([]);
-          } else {
-            // This is not running as a performance test. Continue as normal.
-            window.console.log('Warning: failed to call '
-                'reportPerformanceTestDone. If this is a performance test, '
-                'please include '
-                'packages/browser_controller/perf_test_controller.js in your '
-                'html file.');
-          }
-          return done;
-
-        default:
-          throw 'Unknown command ${command} [${data}]';
-      }
-    };
-
-    done = (String command, var data) {
-    };
-
-    return loading;
-  }
-
-  _css(Element element, String property, String value) {
-    // TODO(antonm): remove the last argument when CallWithDefaultValue
-    // is implemented.
-    element.style.setProperty(property, value, '');
-  }
-
-  Element _byId(String id) {
-    return document.querySelector('#$id');
-  }
-
-  int get _suitesTotal {
-    return _suiteControllers.length;
-  }
-}
diff --git a/samples/third_party/dromaeo/web/LICENSE b/samples/third_party/dromaeo/web/LICENSE
deleted file mode 100644
index 335edf6..0000000
--- a/samples/third_party/dromaeo/web/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-Dromaeo Test Suite
-Copyright (c) 2008 John Resig
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-----
-
-All tests are the copyright of their respective owners.
- - Tests coming from the Computer Language Shootout are under the Revised BSD license
-    <http://shootout.alioth.debian.org/license.php>.
- - Tests coming from John Resig are under an MIT license.
diff --git a/samples/third_party/dromaeo/web/README b/samples/third_party/dromaeo/web/README
deleted file mode 100644
index 4c6f0aa..0000000
--- a/samples/third_party/dromaeo/web/README
+++ /dev/null
@@ -1,57 +0,0 @@
-This is a port of the Dromaeo benchmark (http://dromaeo.com/) to Dart.
-See the attached LICENSE file in this directory.
-
-To run the native Dart versions on Dartium: 
-
-(1) Use a Dartium chrome binary to open index.html in this directory.
-By default, this will run JS vs a native Dart version (dart:html)
-designed to match the JS for speed.
-
-To run compiled versions on standard browsers:
-
-(1) Execute python ./generate_dart2js_tests.py to create frog
-and dart2js variants.
-
-(2) Use a standard browser to open index-js.html in this directory.
-By default, this will run JS vs a dart2js compiled Dart version
-(dart2js:html) designed to match the JS for speed.
-
--------------------------------------------------------
-
-Note, you can run more variants and at a finer granularity.  Dart
-Dromaeo includes the following modes:
-
-- js : The original JS.
-- dart : Dart, running natively (Dartium only).
-- frog : Dart, compiled to JS with Frog.
-- dart2js : Dart, compiled to JS with dart2js.
-
-It also includes the following versions for Dart modes:
-
-- dom : The old deprecated dart:dom.
-- html : The new dart:html, using fast path APIs to match JS.
-
-Finally, Dart Dromaeo runs the following suites of benchmarks:
-- attributes : Setting and getting DOM node attributes.
-- modify : Creating and injecting DOM nodes into a document.
-- query : Querying DOM elements in a document.
-- traverse : Traversing a DOM structure.
-
-You can specify a disjunction of conjunctions from the three buckets
-above.  Examples:
-
-To run the attributes suite on JS, Dartium, and Dart2JS, load:
-
-- index.html?js&attributes|dart&attributes&html|dart2js&attributes&html
-
-To run the query suite with Dart2JS, load:
-
-- index-js.html?dart&query&html
-
-To run all tests in Dartium, load:
-
-- index.html?js|dart|frog|dart2js
-
-To run all tests (except the native Dart) in a regular browser, load:
-
-- index-js.html?js|frog|dart2js
diff --git a/samples/third_party/dromaeo/web/Suites.dart b/samples/third_party/dromaeo/web/Suites.dart
deleted file mode 100644
index eefe856..0000000
--- a/samples/third_party/dromaeo/web/Suites.dart
+++ /dev/null
@@ -1,174 +0,0 @@
-library Suites;
-
-class Origin {
-  final String author;
-  final String url;
-
-  const Origin(this.author, this.url);
-}
-
-class SuiteDescription {
-  final String file;
-  final String name;
-  final Origin origin;
-  final String description;
-  final List<String> tags;
-  final List testVariants;
-
-  const SuiteDescription(this.file, this.name, this.origin,
-                         this.description, this.tags, this.testVariants);
-}
-
-class Suites {
-  static const JOHN_RESIG = const Origin('John Resig', 'http://ejohn.org/');
-
-  static const CATEGORIES = const {
-    // Platform tags
-    'js': 'DOM Core Tests (JavaScript)',
-    'dart': 'DOM Core Tests (dart)',
-    'dart2js': 'DOM Core Tests (dart2js)',
-
-    // Library tags
-    'html': 'DOM Core Tests (dart:html)',
-  };
-
-  static const _CORE_TEST_OPTIONS = const [
-      // A list of valid combinations for core Dromaeo DOM tests.
-      // Each item in the list is a pair of (platform x [variants]).
-      const ['js', const ['']],
-      const ['dart', const ['html']],
-      const ['dart2js', const ['html']],
-    ];
-
-  static const _CORE_SUITE_DESCRIPTIONS = const [
-      const SuiteDescription(
-          'tests/dom-attr.html',
-          'DOM Attributes',
-          JOHN_RESIG,
-          'Setting and getting DOM node attributes',
-          const ['attributes'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          'tests/dom-modify.html',
-          'DOM Modification',
-          JOHN_RESIG,
-          'Creating and injecting DOM nodes into a document',
-          const ['modify'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          'tests/dom-query.html',
-          'DOM Query',
-          JOHN_RESIG,
-          'Querying DOM elements in a document',
-          const ['query'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          'tests/dom-traverse.html',
-          'DOM Traversal',
-          JOHN_RESIG,
-          'Traversing a DOM structure',
-          const ['traverse'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          '/root_dart/tests/html/dromaeo_smoke.html',
-          'Smoke test',
-          const Origin('', ''),
-          'Dromaeo no-op smoke test',
-          const ['nothing'],
-          _CORE_TEST_OPTIONS),
-  ];
-
-  // Mappings from original path to actual path given platform/library.
-  static _getHtmlPathForVariant(platform, lib, path) {
-    if (lib != '') {
-      lib = '-$lib';
-    }
-    switch (platform) {
-      case 'js':
-      case 'dart':
-        return path.replaceFirst('.html', '$lib.html');
-      case 'dart2js':
-        int i = path.indexOf('/');
-        String topLevelDir = '';
-        if (i != -1) topLevelDir = '${path.substring(0, i)}';
-        return '$topLevelDir/'
-            '${path.substring(i + 1).replaceFirst(".html", "$lib-js.html")}';
-    }
-  }
-
-  static var _SUITE_DESCRIPTIONS;
-
-  static List<SuiteDescription> get SUITE_DESCRIPTIONS {
-    if (_SUITE_DESCRIPTIONS != null) {
-      return _SUITE_DESCRIPTIONS;
-    }
-    _SUITE_DESCRIPTIONS = <SuiteDescription>[];
-
-    // Expand the list to include a unique SuiteDescription for each
-    // tested variant.
-    for (SuiteDescription suite in _CORE_SUITE_DESCRIPTIONS) {
-      List variants = suite.testVariants;
-      for (List variant in variants) {
-        assert(variant.length == 2);
-        String platform = variant[0];
-        List<String> libraries = variant[1];
-        for(String lib in libraries) {
-          String path = _getHtmlPathForVariant(platform, lib, suite.file);
-          final combined = new List.from(suite.tags);
-          combined.add(platform);
-          if (lib != '') {
-            combined.add(lib);
-            lib = ':$lib';
-          }
-          final name = (variant == null)
-              ? suite.name
-              : '${suite.name} ($platform$lib)';
-          _SUITE_DESCRIPTIONS.add(new SuiteDescription(
-                                      path,
-                                      name,
-                                      suite.origin,
-                                      suite.description,
-                                      combined,
-                                      []));
-        }
-      }
-    }
-
-    return _SUITE_DESCRIPTIONS;
-  }
-
-  static List<SuiteDescription> getSuites(String tags) {
-    // Allow AND and OR in place of '&' and '|' for browsers where
-    // those symbols are escaped.
-    tags = tags.replaceAll('OR', '|').replaceAll('AND', '&');
-    // A disjunction of conjunctions (e.g.,
-    // 'js&modify|dart&dom&modify').
-    final taglist = tags.split('|').map((tag) => tag.split('&')).toList();
-
-    bool match(suite) {
-      // If any conjunction matches, return true.
-      for (final tagset in taglist) {
-        if (tagset.every((tag) => suite.tags.indexOf(tag) >= 0)) {
-          return true;
-        }
-      }
-      return false;
-    }
-    final suites = SUITE_DESCRIPTIONS.where(match).toList();
-
-    suites.sort((s1, s2) => s1.name.compareTo(s2.name));
-    return suites;
-  }
-
-  static getCategory(String tags) {
-    if (CATEGORIES.containsKey(tags)) {
-      return CATEGORIES[tags];
-    }
-    for (final suite in _CORE_SUITE_DESCRIPTIONS) {
-      if (suite.tags[0] == tags) {
-        return suite.name;
-      }
-    }
-    return null;
-  }
-}
diff --git a/samples/third_party/dromaeo/web/application.css b/samples/third_party/dromaeo/web/application.css
deleted file mode 100644
index e540dd2..0000000
--- a/samples/third_party/dromaeo/web/application.css
+++ /dev/null
@@ -1,115 +0,0 @@
-ol.results { text-align: left; display: none; font-size: 10px; list-style: none; display: none; }
-.alldone ol.results { display: block; width: 48%; float: left; }
-ol.results li { clear: both; overflow: auto; }
-ol.results b { display: block; width: 200px; float: left; text-align: right; padding-right: 15px; }
-#info { clear:both;width:420px;margin:0 auto;text-align:left; padding: 10px; }
-div.results { width:420px;margin:0 auto;margin-bottom:20px;text-align:left; padding: 10px 10px 10px 10px; }
-#info span { font-weight: bold; padding-top: 8px; }
-h1 { text-align: left; }
-h1 img { float:left;margin-right: 15px;margin-top: -10px; border: 0; }
-h1 small { font-weight:normal; }
-iframe { display: none; }
-div.resultwrap { text-align: center; }
-table.results { font-size: 12px; margin: 0 auto; }
-table.results td, table.results th.name, table.results th { text-align: right; }
-table.results .winner { color: #000; background-color: #c7331d; }
-table.results .tie { color: #000; background-color: #f9f2a1; }
-
-body  {
-	font: normal 11px "Lucida Grande", Helvetica, Arial, sans-serif;
-	background: black url(images/bg.png) repeat-x;
-	margin: 0px auto;
-	padding: 0px; 
-	color: #eee; 
-	text-align: center;
-	line-height: 180%;
-}	
-div, img, form, ul {
-	margin: 0px; 
-	padding: 0px;
-	border: 0px; 
-}
-small			{font-size: 9px;}
-div, span, td, .text_l {text-align: left;}	
-.clear 			{clear: both;}	
-.text_r 		{text-align: right;}
-.text_c 		{text-align: center;}
-a 				{font: normal  "Arial", sans-serif; color: #f9f2a1; }
-.left 			{float: left;}
-.right 			{float: right;}
-
-#wrapper 		{width: 690px; margin: 0px auto; padding: 0px; margin-top: -7px; text-align: center;}
-#content		{margin-bottom: 30px;}
-#main			{padding-bottom: 40px;}
-
-#top			{background: url(images/top.png) repeat-x; height: 250px;}
-#logo			{position: absolute; top: 0; left: 0; width: 100%; text-align: center; z-index: 100;}
-#logo img		{ margin: 0px auto; padding: 0px;}
-.dino1			{position: absolute; top: 105px; right: 300px; z-index: 15;}
-.dino2			{position: absolute; top: 110px; left: 15%;  z-index: 12;}
-.dino3			{position: absolute; top: 120px; left: 400px;  z-index: 31;}
-.dino4			{position: absolute; top: 96px; left: 200px;  z-index: 8;}
-.dino5			{position: absolute; top: 110px; right: 85px;  z-index: 14;}
-.dino6			{position: absolute; top: 105px; left: 30%;  z-index: 14;}
-.dino7			{position: absolute; top: 110px; left: 70%;  z-index: 22;}
-.dino8			{position: absolute; top: 105px; left: 37%;  z-index: 20;}
-.coment			{position: absolute; top: 0px; right: 0px;  z-index: 2; float: right;}
-
-.clouds			{position: absolute; top: 10px; right: 11%;  z-index: 12;}
-.clouds2		{position: absolute; top: 50px; right: 29%;  z-index: 13;}
-.clouds5		{position: absolute; top: 0px; right: 15%;  z-index: 16;}
-.clouds3			{position: absolute; top: 15px; left: 10%;  z-index: 15;}
-.clouds4		{position: absolute; top: 10px; left: 15%;  z-index: 14;}
-
-.water		{position: absolute; top: 110px; right: 9%;  z-index: 13;}
-
-
-/* rendered html stuff */
-
-table.results	{text-align: center; margin: 0px auto; padding: 0px; background: none;}
-table.results td, table.results th 			{padding: 2px;}
-table.results tr.onetest td, table.results tr.onetest th 			{padding: 0px;}
-table.results tr.hidden { display: none; }
-#info			{margin-bottom: 10px;}
-table.results .winner			{background: #58bd79;}
-.name			{font-weight: bold;}
-
-div.resultwrap	{margin: 10px 0 10px 0;}
-div.results		{padding: 10px; margin-bottom: 20px; background: #c7331d;}
-
-div.result-item { position: relative; width: 48%; float: left; overflow: hidden; margin-left: 1%; margin-right: 1%; height: 100px; }
-.alldone div.result-item { width: 98%; height: auto; margin-bottom: 10px; overflow: auto; }
-.alldone div.result-item p { width: 48%; float: left; }
-
-div.result-item p { padding: 0px 4px; }
-
-div.test { overflow: hidden; margin: 4px 0; }
-div.test b { display: block; width: 100%; text-align: left; margin: 0px; background: #c7331d; padding: 4px; }
-/*div.done div.test b {background: #58bd79;}*/
-div.done div.test b {background: #222;}
-div.bar { width: 100px; border: 1px inset #666; background: #c7331d; text-align: left; position: absolute; top: 7px; right: 4px; }
-div.bar div { height: 20px; background: #222; text-align: right; }
-div.done div.bar div {background: #58bd79; color: #000;}
-div.bar span { padding-left: 5px; padding-right: 5px; }
-
-#info { margin: auto; }
-
-h1 { font-size: 28px; border-bottom: 1px solid #AAA; position: relative; padding: 0px 1% 2px 1%;}
-h1 div.bar { font-size: 10px; width: 275px; top: -2px; right: 1%; }
-h1 input { position: absolute; top: 0px; right: 300px; }
-
-h2 { font-size: 20px; border-bottom: 1px solid #AAA; position: relative; padding: 0px 1% 2px 1%;}
-h2 a { color: #FFF; }
-h2 div.bar { font-size: 10px; width: 275px; top: -2px; right: 1%; }
-h2 input { position: absolute; top: 0px; right: 300px; }
-
-ul#tests { clear:both;width:420px;margin:0 auto;text-align:left; padding: 10px; list-style: none; }
-#tests b { background: #c7331d; color: #000; display: block; padding: 4px 0 4px 4px; margin-left: -20px; margin-bottom: 5px; font-size: 1.1em; -webkit-border-radius: 4px; -moz-border-radius: 4px; font-weight: normal; }
-#tests b.recommended { background: #58bd79; }
-#tests a:first-of-type { font-size: 1.2em; }
-#tests b a { font-weight: bold; color: #000; }
-#tests li { padding-left: 10px; padding-bottom: 5px; }
-
-#overview { position: relative; }
-#overview a { font-size: 10px; top: -29px; left: 8px; position: absolute; }
-#overview table a { position: static; }
diff --git a/samples/third_party/dromaeo/web/common/BenchUtil.dart b/samples/third_party/dromaeo/web/common/BenchUtil.dart
deleted file mode 100644
index 5a4b9c7..0000000
--- a/samples/third_party/dromaeo/web/common/BenchUtil.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011, 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.
-
-part of common;
-
-// Misc benchmark-related utility functions.
-
-class BenchUtil {
-  static int get now {
-    return new DateTime.now().millisecondsSinceEpoch;
-  }
-
-  static Map<String, Object> deserialize(String data) {
-    return JSON.decode(data);
-  }
-
-  static String serialize(Object obj) {
-    return JSON.encode(obj);
-  }
-
-  // Shuffle a list randomly.
-  static void shuffle(List<Object> list) {
-    int len = list.length - 1;
-    for (int i = 0; i < len; i++) {
-      int index = (Math.random() * (len - i)).toInt() + i;
-      Object tmp = list[i];
-      list[i] = list[index];
-      list[index] = tmp;
-    }
-  }
-
-  static String formatGolemData(String prefix, Map<String, num> results) {
-    List<String> elements = new List<String>();
-    results.forEach((String name, num score) {
-      elements.add('"${prefix}/${name}":${score}');
-    });
-    return serialize(elements);
-  }
-
-  static bool _inRange(int charCode, String start, String end) {
-    return start.codeUnitAt(0) <= charCode && charCode <= end.codeUnitAt(0);
-  }
-
-  static const String DIGITS = '0123456789ABCDEF';
-  static String _asDigit(int value) {
-    return DIGITS[value];
-  }
-
-  static String encodeUri(final String s) {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < s.length; i++) {
-      final int charCode = s.codeUnitAt(i);
-      final bool noEscape =
-          _inRange(charCode, '0', '9') ||
-          _inRange(charCode, 'a', 'z') ||
-          _inRange(charCode, 'A', 'Z');
-      if (noEscape) {
-        sb.write(s[i]);
-      } else {
-       sb.write('%');
-       sb.write(_asDigit((charCode >> 4) & 0xF));
-       sb.write(_asDigit(charCode & 0xF));
-      }
-    }
-    return sb.toString();
-  }
-
-  // TODO: use corelib implementation.
-  static String replaceAll(String s, String pattern,
-                           String replacement(Match match)) {
-    StringBuffer sb = new StringBuffer();
-
-    int pos = 0;
-    for (Match match in new RegExp(pattern).allMatches(s)) {
-      sb.write(s.substring(pos, match.start));
-      sb.write(replacement(match));
-      pos = match.end;
-    }
-    sb.write(s.substring(pos));
-
-    return sb.toString();
-  }
-}
diff --git a/samples/third_party/dromaeo/web/common/Interval.dart b/samples/third_party/dromaeo/web/common/Interval.dart
deleted file mode 100644
index 50d2d84..0000000
--- a/samples/third_party/dromaeo/web/common/Interval.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2011, 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.
-
-part of common;
-
-// A utility object for measuring time intervals.
-
-class Interval {
-  int _start, _stop;
-
-  Interval() {
-  }
-
-  void start() {
-    _start = BenchUtil.now;
-  }
-
-  void stop() {
-    _stop = BenchUtil.now;
-  }
-
-  // Microseconds from between start() and stop().
-  int get elapsedMicrosec {
-    return (_stop - _start) * 1000;
-  }
-
-  // Milliseconds from between start() and stop().
-  int get elapsedMillisec {
-    return (_stop - _start);
-  }
-}
diff --git a/samples/third_party/dromaeo/web/common/Math2.dart b/samples/third_party/dromaeo/web/common/Math2.dart
deleted file mode 100644
index 20f08fa..0000000
--- a/samples/third_party/dromaeo/web/common/Math2.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2011, 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.
-
-part of common;
-
-// Various math-related utility functions.
-
-class Math2 {
-  /// Computes the geometric mean of a set of numbers.
-  /// [minNumber] is optional (defaults to 0.001) anything smaller than this
-  /// will be changed to this value, eliminating infinite results.
-  static double geometricMean(List<double> numbers,
-                              [double minNumber = 0.001]) {
-    double log = 0.0;
-    int nNumbers = 0;
-    for (int i = 0, n = numbers.length; i < n; i++) {
-      double number = numbers[i];
-      if (number < minNumber) {
-        number = minNumber;
-      }
-      nNumbers++;
-      log += Math.log(number);
-    }
-
-    return nNumbers > 0 ? Math.pow(Math.E, log / nNumbers) : 0.0;
-  }
-
-  static int round(double d) {
-    return d.round();
-  }
-
-  static int floor(double d) {
-    return d.floor();
-  }
-
-  // TODO (olonho): use d.toStringAsFixed(precision) when implemented by DartVM
-  static String toStringAsFixed(num d, int precision) {
-    String dStr = d.toString();
-    int pos = dStr.indexOf('.', 0);
-    int end = pos < 0 ? dStr.length : pos + precision;
-    if (precision > 0) {
-      end++;
-    }
-    if (end > dStr.length) {
-      end = dStr.length;
-    }
-
-    return dStr.substring(0, end);
-  }
-}
diff --git a/samples/third_party/dromaeo/web/common/common.dart b/samples/third_party/dromaeo/web/common/common.dart
deleted file mode 100644
index 5a33126..0000000
--- a/samples/third_party/dromaeo/web/common/common.dart
+++ /dev/null
@@ -1,10 +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 common;
-import 'dart:math' as Math;
-import "dart:convert";
-part 'BenchUtil.dart';
-part 'Interval.dart';
-part 'Math2.dart';
diff --git a/samples/third_party/dromaeo/web/favicon.ico b/samples/third_party/dromaeo/web/favicon.ico
deleted file mode 100644
index d444389..0000000
--- a/samples/third_party/dromaeo/web/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/favicon.png b/samples/third_party/dromaeo/web/favicon.png
deleted file mode 100644
index d772102..0000000
--- a/samples/third_party/dromaeo/web/favicon.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/htmlrunner.js b/samples/third_party/dromaeo/web/htmlrunner.js
deleted file mode 100644
index 8f565c4..0000000
--- a/samples/third_party/dromaeo/web/htmlrunner.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// An version of Dromaeo's original htmlrunner adapted for the
-// Dart-based test driver.
-
-var _operations = [];
-var _N_RUNS = 5;
-var _nRanTests = 0;
-var _nTests = 0;
-var _T_DISTRIBUTION = 2.776;
-
-function startTest() {
-  window.addEventListener(
-      'message',
-      function (event) {
-        if (event.data == 'start') {
-          _run();
-        } else {
-          window.alert('Unknown command: ' + event.data);
-        }
-      },
-      false);
-}
-
-function _run() {
-  var currentOperation = 0;
-  function handler() {
-    if (currentOperation < _operations.length) {
-      _operations[currentOperation]();
-      currentOperation++;
-      window.setTimeout(handler, 1);
-    } else {
-      _postMessage('over');
-    }
-  }
-  window.setTimeout(handler, 0);
-}
-
-function _postMessage(command, data) {
-  var payload = { 'command': command };
-  if (data) {
-    payload['data'] = data;
-  }
-  window.parent.postMessage(JSON.stringify(payload), '*');
-}
-
-function test(name, fn) {
-  _nTests++;
-  _operations.push(function () {
-      // List of number of runs in seconds.
-      var runsPerSecond = [];
-      // Run the test several times.
-      try {
-        // TODO(antonm): use .setTimeout to schedule next run as JS
-        // version does.  That allows to report the intermediate results
-        // more smoothly as well.
-        for (var i = 0; i < _N_RUNS; i++) {
-          var runs = 0;
-          var start = Date.now();
-
-          var cur = Date.now();
-          while ((cur - start) < 1000) {
-            fn();
-            cur = Date.now();
-            runs++;
-          }
-
-          runsPerSecond.push((runs * 1000.0) / (cur - start));
-        }
-      } catch(e) {
-        window.alert('Exception : ' + e);
-        return;
-      }
-      _reportTestResults(name, runsPerSecond);
-    });
-}
-
-// Adapted from Dromaeo's webrunner.
-function _compute(times){
-  var results = {runs: times.length}, num = times.length;
-
-  times = times.sort(function(a,b){
-      return a - b;
-    });
-
-  // Make Sum
-  results.sum = 0;
-
-  for ( var i = 0; i < num; i++ )
-    results.sum += times[i];
-
-  // Make Min
-  results.min = times[0];
-
-  // Make Max
-  results.max = times[ num - 1 ];
-
-  // Make Mean
-  results.mean = results.sum / num;
-
-  // Make Median
-  results.median = num % 2 == 0 ?
-      (times[Math.floor(num/2)] + times[Math.ceil(num/2)]) / 2 :
-      times[Math.round(num/2)];
-
-  // Make Variance
-  results.variance = 0;
-
-  for ( var i = 0; i < num; i++ )
-    results.variance += Math.pow(times[i] - results.mean, 2);
-
-  results.variance /= num - 1;
-
-  // Make Standard Deviation
-  results.deviation = Math.sqrt( results.variance );
-
-  // Compute Standard Errors Mean
-  results.sem = (results.deviation / Math.sqrt(results.runs)) * _T_DISTRIBUTION;
-
-  // Error
-  results.error = ((results.sem / results.mean) * 100) || 0;
-
-  return results;
-}
-
-function _reportTestResults(name, times) {
-  _nRanTests++;
-  var results = _compute(times);
-
-  _postMessage('result', {
-      'testName': name,
-      'mean': results.mean,
-      'error': results.error,
-      'percent': (100.0 * _nRanTests / _nTests)
-          });
-}
-
-function endTest() {
-  _postMessage('inited', { 'nTests': _nTests });
-}
-
-function prep(fn) {
-  _operations.push(fn);
-}
diff --git a/samples/third_party/dromaeo/web/images/bg.png b/samples/third_party/dromaeo/web/images/bg.png
deleted file mode 100644
index bd659a8..0000000
--- a/samples/third_party/dromaeo/web/images/bg.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/clouds.png b/samples/third_party/dromaeo/web/images/clouds.png
deleted file mode 100644
index c9f7dc2..0000000
--- a/samples/third_party/dromaeo/web/images/clouds.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/clouds2.png b/samples/third_party/dromaeo/web/images/clouds2.png
deleted file mode 100644
index ac835dc..0000000
--- a/samples/third_party/dromaeo/web/images/clouds2.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/comets.png b/samples/third_party/dromaeo/web/images/comets.png
deleted file mode 100644
index 37dd962..0000000
--- a/samples/third_party/dromaeo/web/images/comets.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino1.png b/samples/third_party/dromaeo/web/images/dino1.png
deleted file mode 100644
index 2dda272..0000000
--- a/samples/third_party/dromaeo/web/images/dino1.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino2.png b/samples/third_party/dromaeo/web/images/dino2.png
deleted file mode 100644
index ccfa15c..0000000
--- a/samples/third_party/dromaeo/web/images/dino2.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino3.png b/samples/third_party/dromaeo/web/images/dino3.png
deleted file mode 100644
index a766b28..0000000
--- a/samples/third_party/dromaeo/web/images/dino3.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino4.png b/samples/third_party/dromaeo/web/images/dino4.png
deleted file mode 100644
index 03301d3..0000000
--- a/samples/third_party/dromaeo/web/images/dino4.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino5.png b/samples/third_party/dromaeo/web/images/dino5.png
deleted file mode 100644
index 5fd028d..0000000
--- a/samples/third_party/dromaeo/web/images/dino5.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino6.png b/samples/third_party/dromaeo/web/images/dino6.png
deleted file mode 100644
index ded8106..0000000
--- a/samples/third_party/dromaeo/web/images/dino6.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino7.png b/samples/third_party/dromaeo/web/images/dino7.png
deleted file mode 100644
index ac2021b..0000000
--- a/samples/third_party/dromaeo/web/images/dino7.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino8.png b/samples/third_party/dromaeo/web/images/dino8.png
deleted file mode 100644
index a4b1fe4..0000000
--- a/samples/third_party/dromaeo/web/images/dino8.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/left.png b/samples/third_party/dromaeo/web/images/left.png
deleted file mode 100644
index b688f2b..0000000
--- a/samples/third_party/dromaeo/web/images/left.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/logo.png b/samples/third_party/dromaeo/web/images/logo.png
deleted file mode 100644
index 199fda7..0000000
--- a/samples/third_party/dromaeo/web/images/logo.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/logo2.png b/samples/third_party/dromaeo/web/images/logo2.png
deleted file mode 100644
index 427687f..0000000
--- a/samples/third_party/dromaeo/web/images/logo2.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/logo3.png b/samples/third_party/dromaeo/web/images/logo3.png
deleted file mode 100644
index 306c485..0000000
--- a/samples/third_party/dromaeo/web/images/logo3.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/right.png b/samples/third_party/dromaeo/web/images/right.png
deleted file mode 100644
index 154cb41..0000000
--- a/samples/third_party/dromaeo/web/images/right.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/top.png b/samples/third_party/dromaeo/web/images/top.png
deleted file mode 100644
index 24039c3..0000000
--- a/samples/third_party/dromaeo/web/images/top.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/water.png b/samples/third_party/dromaeo/web/images/water.png
deleted file mode 100644
index 40a0f0d..0000000
--- a/samples/third_party/dromaeo/web/images/water.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/index.html b/samples/third_party/dromaeo/web/index.html
deleted file mode 100644
index f03b22f..0000000
--- a/samples/third_party/dromaeo/web/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <meta http-equiv="Content-Type" content="text/html; utf-8" />
-  <title>Dromaeo: JavaScript Performance Testing</title>
-  <link href="reset.css" rel="stylesheet" type="text/css" />
-  <link href="application.css" rel="stylesheet" type="text/css" />
-  <script type="application/dart" src="Dromaeo.dart"></script>
-  <script src="packages/browser/dart.js"></script>
-</head>
-<body>
-        <div id="top" >
-          <div id="logo">
-            <a href="./"><img src="images/logo3.png" class="png"/></a>
-          </div>
-          <img src="images/dino1.png" class="dino1 png"/>
-          <img src="images/left.png" class="left png"/>
-          <img src="images/dino2.png" class="dino2 png"/>
-          <img src="images/dino2.png" class="dino2 png"/>
-          <img src="images/dino3.png" class="dino3 png"/>
-          <img src="images/dino4.png" class="dino4 png"/>
-          <img src="images/dino5.png" class="dino5 png"/>
-          <img src="images/dino7.png" class="dino7 png"/>
-          <img src="images/dino8.png" class="dino8 png"/>
-          <img src="images/dino6.png" class="dino6 png"/>
-          <img src="images/clouds2.png" class="clouds2 png"/>
-          <img src="images/clouds.png" class="clouds png"/>
-          <img src="images/clouds2.png" class="clouds3 png"/>
-          <img src="images/clouds.png" class="clouds4 png"/>
-          <img src="images/clouds2.png" class="clouds5 png"/>
-          <img src="images/comets.png" class="right png"/>
-        </div>
-        <div id="wrapper">
-        <div id="main">
-<div id="info"><span>Mozilla JavaScript performance test suite.</span><br/>More information about <a href="http://wiki.mozilla.org/Dromaeo">Dromaeo</a> can be found on the Mozilla wiki.</div>
-<h1 id="overview" class="test"><span>Performance Tests</span> <input type="button" id="pause" class="pause" value="Loading..."/><div class="bar"><div id="timebar" style="width:25%;"><span class="left">Est.&nbsp;Time:&nbsp;<strong id="left">0:00</strong></span></div></div><a href="./">&laquo; View All Tests</a></h1><br style="clear:both;"/>
-<ul id="tests">
-  <li><a href="?dom">DOM Core Tests</a><br/>(Tests DOM Querying, Traversing, Manipulation, and Attributes.)</li>
-</ul>
-</div>
-</div>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/reset.css b/samples/third_party/dromaeo/web/reset.css
deleted file mode 100644
index 4a3cf94..0000000
--- a/samples/third_party/dromaeo/web/reset.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -------------------------------------------------------------- 
-  
-   reset.css
-   * Resets default browser CSS.
-   
-   Based on work by Eric Meyer:
-   * meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
-   
--------------------------------------------------------------- */
-
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, code,
-del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	font-weight: inherit;
-	font-style: inherit;
-	font-size: 100%;
-	font-family: inherit;
-	vertical-align: baseline;
-}
-
-
-body { line-height: 1.5; background: #fff; margin:1.5em 0; }
-
-/* Tables still need 'cellspacing="0"' in the markup. */
-caption, th, td { text-align: left; font-weight:400; }
-
-/* Remove possible quote marks (") from <q>, <blockquote>. */
-blockquote:before, blockquote:after, q:before, q:after { content: ""; }
-blockquote, q { quotes: "" ""; }
-
-a img { border: none; }
-
diff --git a/samples/third_party/dromaeo/web/test-head.html b/samples/third_party/dromaeo/web/test-head.html
deleted file mode 100644
index 481251c..0000000
--- a/samples/third_party/dromaeo/web/test-head.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
diff --git a/samples/third_party/dromaeo/web/test-tail.html b/samples/third_party/dromaeo/web/test-tail.html
deleted file mode 100644
index 1b4431b..0000000
--- a/samples/third_party/dromaeo/web/test-tail.html
+++ /dev/null
@@ -1,4 +0,0 @@
-</script>
-</head>
-<body></body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/Common.dart b/samples/third_party/dromaeo/web/tests/Common.dart
deleted file mode 100644
index f763fb9..0000000
--- a/samples/third_party/dromaeo/web/tests/Common.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-part of dromaeo;
-
-class Result {
-  int get runs { return _sorted.length; }
-
-  double get sum {
-    double result = 0.0;
-    _sorted.forEach((double e) { result += e; });
-    return result;
-  }
-
-  double get min { return _sorted[0]; }
-  double get max { return _sorted[runs - 1]; }
-
-  double get mean { return sum / runs; }
-
-  double get median {
-    return (runs % 2 == 0) ?
-        (_sorted[runs ~/ 2] + _sorted[runs ~/ 2 + 1]) / 2 : _sorted[runs ~/ 2];
-  }
-
-  double get variance {
-    double m = mean;
-    double result = 0.0;
-    _sorted.forEach((double e) { result += Math.pow(e - m, 2.0); });
-    return result / (runs - 1);
-  }
-
-  double get deviation { return Math.sqrt(variance); }
-
-  // Compute Standard Errors Mean
-  double get sem { return (deviation / Math.sqrt(runs)) * T_DISTRIBUTION; }
-
-  double get error { return (sem / mean) * 100; }
-
-  // TODO: Implement writeOn.
-  String toString() {
-    return '[Result: mean = ${mean}]';
-  }
-
-  factory Result(List<double> runsPerSecond) {
-    runsPerSecond.sort((a, b) => a.compareTo(b));
-    return new Result._internal(runsPerSecond);
-  }
-
-  Result._internal(this._sorted) {}
-
-  List<double> _sorted;
-
-  // Populated from: http://www.medcalc.be/manual/t-distribution.php
-  // 95% confidence for N - 1 = 4
-  static const double T_DISTRIBUTION = 2.776;
-}
diff --git a/samples/third_party/dromaeo/web/tests/RunnerSuite.dart b/samples/third_party/dromaeo/web/tests/RunnerSuite.dart
deleted file mode 100644
index e1e0945..0000000
--- a/samples/third_party/dromaeo/web/tests/RunnerSuite.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-part of dromaeo;
-
-typedef void Test();
-typedef void Operation();
-typedef void Reporter(Map<String, Result> results);
-
-class Suite {
-  /**
-   * Ctor.
-   *  [:_window:] The window of the suite.
-   *  [:_name:] The name of the suite.
-   */
-  Suite(this._window, this._name) :
-      _operations = new List<Operation>(),
-      _nTests = 0, _nRanTests = 0 {
-    starter(MessageEvent event) {
-      String command = event.data;
-      switch (command) {
-        case 'start':
-          _run();
-          return;
-        default:
-          _window.alert('[${_name}]: unknown command ${command}');
-      }
-    };
-    _window.onMessage.listen(starter);
-  }
-
-  /**
-   * Adds a preparation step to the suite.
-   * [:operation:] The operation to be performed.
-   */
-  Suite prep(Operation operation){
-    return _addOperation(operation);
-  }
-
-  // How many times each individual test should be ran.
-  static const int _N_RUNS = 5;
-
-  /**
-   * Adds another test to the suite.
-   * [:name:] The unique name of the test
-   * [:test:] A function holding the test to run
-   */
-  Suite test(String name, Test test_) {
-    _nTests++;
-    // Don't execute the test immediately.
-    return _addOperation(() {
-      // List of number of runs in seconds.
-      List<double> runsPerSecond = new List<double>();
-
-      // Run the test several times.
-      try {
-        // TODO(antonm): use timer to schedule next run as JS
-        // version does.  That allows to report the intermidiate results
-        // more smoothly as well.
-        for (int i = 0; i < _N_RUNS; i++) {
-          int runs = 0;
-          final int start = new DateTime.now().millisecondsSinceEpoch;
-
-          int cur = new DateTime.now().millisecondsSinceEpoch;
-          while ((cur - start) < 1000) {
-            test_();
-            cur = new DateTime.now().millisecondsSinceEpoch;
-            runs++;
-          }
-
-          runsPerSecond.add((runs * 1000.0) / (cur - start));
-        }
-      } catch (exception, stacktrace) {
-        _window.alert('Exception ${exception}: ${stacktrace}');
-        return;
-      }
-      _reportTestResults(name, new Result(runsPerSecond));
-    });
-  }
-
-  /**
-   * Finalizes the suite.
-   * It might either run the tests immediately or schedule them to be ran later.
-   */
-  void end() {
-    _postMessage('inited', { 'nTests': _nTests });
-
-  }
-
-  _run() {
-    int currentOperation = 0;
-    handler() {
-      if (currentOperation < _operations.length) {
-        _operations[currentOperation]();
-        currentOperation++;
-        new Timer(const Duration(milliseconds: 1), handler);
-      } else {
-        _postMessage('over');
-      }
-    }
-    Timer.run(handler);
-  }
-
-  _reportTestResults(String name, Result result) {
-    _nRanTests++;
-    _postMessage('result', {
-        'testName': name,
-        'mean': result.mean,
-        'error': result.error,
-        'percent': (100.0 * _nRanTests / _nTests)
-    });
-  }
-
-  _postMessage(String command, [var data = null]) {
-    final payload = { 'command': command };
-    if (data != null) {
-      payload['data'] = data;
-    }
-    _window.parent.postMessage(JSON.encode(payload), '*');
-  }
-
-  // Implementation.
-
-  final Window _window;
-  final String _name;
-
-  List<Operation> _operations;
-  int _nTests;
-  int _nRanTests;
-
-  Suite _addOperation(Operation operation) {
-    _operations.add(operation);
-    return this;
-  }
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-attr-html.dart b/samples/third_party/dromaeo/web/tests/dom-attr-html.dart
deleted file mode 100644
index f1b1031..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-attr-html.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import "dart:convert";
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-void main() {
-  final int num = 10240;
-
-  // Try to force real results.
-  var ret;
-
-  Element elem = document.querySelector('#test1');
-  Element a = document.querySelector('a');
-
-  new Suite(window, 'dom-attr')
-    .test('getAttribute', () {
-      for (int i = 0; i < num; i++)
-        ret = elem.getAttribute('id');
-    })
-    .test('element.property', () {
-      for (int i = 0; i < num * 2; i++)
-        ret = elem.id;
-    })
-    .test('setAttribute', () {
-        for (int i = 0; i < num; i++)
-          a.setAttribute('id', 'foo');
-    })
-    .test('element.property = value', () {
-      for (int i = 0; i < num; i++)
-        a.id = 'foo';
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-attr-html.html b/samples/third_party/dromaeo/web/tests/dom-attr-html.html
deleted file mode 100644
index 62079e6..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-attr-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-attr-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-attr.html b/samples/third_party/dromaeo/web/tests/dom-attr.html
deleted file mode 100644
index 29ff125..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-attr.html
+++ /dev/null
@@ -1,2946 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-attr");
-
-// Try to force real results
-var ret, tmp;
-
-var elem = document.getElementById("test1");
-var a = document.getElementsByTagName("a")[0];
-var num = 10240;
-	
-	test( "getAttribute", function(){
-		for ( var i = 0; i < num; i++ )
-			ret = elem.getAttribute("id");
-	});
-
-	test( "element.property", function(){
-		for ( var i = 0; i < num * 2; i++ )
-			ret = elem.id;
-	});
-
-	test( "setAttribute", function(){
-		for ( var i = 0; i < num; i++ )
-			a.setAttribute("id", "foo");
-	});
-
-	test( "element.property = value", function(){
-		for ( var i = 0; i < num; i++ )
-			a.id = "foo";
-	});
-
-        // Removing these two as Dart has no expandos.
-        /*
-	test( "element.expando = value", function(){
-		for ( var i = 0; i < num; i++ )
-			a["test" + num] = function(){};
-	});
-
-	test( "element.expando", function(){
-		for ( var i = 0; i < num; i++ )
-			ret = a["test" + num];
-	});
-        */
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-modify-html.dart b/samples/third_party/dromaeo/web/tests/dom-modify-html.dart
deleted file mode 100644
index e9cb8be..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-modify-html.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import "dart:convert";
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-void main() {
-  final int num = 400;
-  var random = new Math.Random();
-
-  String str = 'null';
-  // Very ugly way to build up the string, but let's mimic JS version as much as
-  // possible.
-  for (int i = 0; i < 1024; i++) {
-    str += new String.fromCharCode(((25 * random.nextDouble()) + 97).toInt());
-  }
-
-  List<Node> elems = <Node>[];
-
-  // Try to force real results.
-  var ret;
-
-  final htmlstr = document.body.innerHtml;
-
-  new Suite(window, 'dom-modify')
-    .test('createElement', () {
-      for (int i = 0; i < num; i++) {
-        ret = new Element.tag('div');
-        ret = new Element.tag('span');
-        ret = new Element.tag('table');
-        ret = new Element.tag('tr');
-        ret = new Element.tag('select');
-      }
-    })
-    .test('createTextNode', () {
-      for (int i = 0; i < num; i++) {
-        ret = new Text(str);
-        ret = new Text('${str}2');
-        ret = new Text('${str}3');
-        ret = new Text('${str}4');
-        ret = new Text('${str}5');
-      }
-    })
-    .test('innerHtml', () {
-      document.body.innerHtml = htmlstr;
-    })
-    .prep(() {
-      elems = new List<Node>();
-      final telems = document.body.nodes;
-      for (int i = 0; i < telems.length; i++) {
-        elems.add(telems[i]);
-      }
-    })
-    .test('cloneNode', () {
-      for (int i = 0; i < elems.length; i++) {
-        ret = elems[i].clone(false);
-        ret = elems[i].clone(true);
-        ret = elems[i].clone(true);
-        }
-    })
-    .test('appendChild', () {
-      for (int i = 0; i < elems.length; i++)
-        document.body.append(elems[i]);
-    })
-    .test('insertBefore', () {
-      for (int i = 0; i < elems.length; i++)
-        document.body.insertBefore(elems[i], document.body.firstChild);
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-modify-html.html b/samples/third_party/dromaeo/web/tests/dom-modify-html.html
deleted file mode 100644
index 4663c13..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-modify-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-modify-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-modify.html b/samples/third_party/dromaeo/web/tests/dom-modify.html
deleted file mode 100644
index 0229892..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-modify.html
+++ /dev/null
@@ -1,2973 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-modify");
-
-// Try to force real results
-var ret, tmp, str;
-
-var elems = [];
-var htmlstr = document.body.innerHTML;
-var div = document.createElement("div");
-var num = 400;
-
-for ( var i = 0; i < 1024; i++ )
-        str += String.fromCharCode( (25 * Math.random()) + 97 );
-
-	test( "createElement", function(){
-		for ( var i = 0; i < num; i++ ) {
-			ret = document.createElement("div");
-			ret = document.createElement("span");
-			ret = document.createElement("table");
-			ret = document.createElement("tr");
-			ret = document.createElement("select");
-		}
-	});
-
-	test( "createTextNode", function(){
-		for ( var i = 0; i < num; i++ ) {
-			ret = document.createTextNode(str);
-			ret = document.createTextNode(str + "2");
-			ret = document.createTextNode(str + "3");
-			ret = document.createTextNode(str + "4");
-			ret = document.createTextNode(str + "5");
-		}
-	});
-
-	/* Need a better way to test this
-	test( "removeChild", function(){
-		while ( document.body.firstChild )
-			document.body.removeChild( document.body.firstChild );
-	});
-	*/
-
-	test( "innerHtml", function(){
-		document.body.innerHTML = htmlstr;
-	});
-
-	prep(function(){
-		elems = [];
-		var telems = document.body.childNodes;
-		for ( var i = 0; i < telems.length; i++ )
-			elems.push( telems[i] );
-	});
-
-	test( "cloneNode", function(){
-		for ( var i = 0; i < elems.length; i++ ) {
-			ret = elems[i].cloneNode(false);
-			ret = elems[i].cloneNode(true);
-			ret = elems[i].cloneNode(true);
-		}
-	});
-
-	test( "appendChild", function(){
-		for ( var i = 0; i < elems.length; i++ )
-			document.body.appendChild( elems[i] );
-	});
-
-	test( "insertBefore", function(){
-		for ( var i = 0; i < elems.length; i++ )
-			document.body.insertBefore( elems[i], document.body.firstChild );
-	});
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
-
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators.
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment:
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element.
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element.
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML
-paragraph that will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag
-sequence. The other lines will be treated as
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt;
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt;
-S
-&lt;/P::first-letter&gt;ome text that
-&lt;/P::first-line&gt;
-ends up on two lines
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree.
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>:
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-
-<p>Selectors can be used in STTS 3 in two different
-    manners:
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification.
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-query-html.dart b/samples/third_party/dromaeo/web/tests/dom-query-html.dart
deleted file mode 100644
index cd58782..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-query-html.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import '../common/common.dart';
-import "dart:convert";
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-void main() {
-  final int num = 40;
-
-  // Try to force real results.
-  var ret;
-
-  String html = document.body.innerHtml;
-
-  new Suite(window, 'dom-query')
-    .prep(() {
-      html = BenchUtil.replaceAll(html, 'id="test(\\w).*?"', (Match match) {
-        final group = match.group(1);
-        return 'id="test${group}${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'name="test.*?"', (Match match) {
-        return 'name="test${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'class="foo.*?"', (Match match) {
-        return 'class="foo test${num} bar"';
-      });
-      final div = new Element.tag('div');
-      div.innerHtml = html;
-      document.body.append(div);
-    })
-    .test('getElementById', () {
-      for (int i = 0; i < num * 30; i++) {
-        ret = document.getElementById('testA$num').nodeType;
-        ret = document.getElementById('testB$num').nodeType;
-        ret = document.getElementById('testC$num').nodeType;
-        ret = document.getElementById('testD$num').nodeType;
-        ret = document.getElementById('testE$num').nodeType;
-        ret = document.getElementById('testF$num').nodeType;
-      }
-    })
-    .test('getElementById (not in document)', () {
-      for (int i = 0; i < num * 30; i++) {
-        ret = document.getElementById('testA');
-        ret = document.getElementById('testB');
-        ret = document.getElementById('testC');
-        ret = document.getElementById('testD');
-        ret = document.getElementById('testE');
-        ret = document.getElementById('testF');
-      }
-    })
-    .test('getElementsByTagName(div)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('div');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName(p)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('p');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName(a)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('a');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName(*)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('*');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName (not in document)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('strong');
-        ret = elems.length == 0;
-      }
-    })
-    .test('getElementsByName', () {
-      for (int i = 0; i < num * 20; i++) {
-        List<Element> elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-        elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-        elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-        elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-      }
-    })
-    .test('getElementsByName (not in document)', () {
-      for (int i = 0; i < num * 20; i++) {
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-      }
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-query-html.html b/samples/third_party/dromaeo/web/tests/dom-query-html.html
deleted file mode 100644
index 27f9333..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-query-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-query-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="testF10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2 id="testA10"><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2 id="testB10"><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2 id="testC10"><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2 id="testD10"><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2 id="testE10"><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-query.html b/samples/third_party/dromaeo/web/tests/dom-query.html
deleted file mode 100644
index 07acf16..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-query.html
+++ /dev/null
@@ -1,3000 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-query");
-
-// Try to force real results
-var ret, tmp;
-var num = 40;
-var html = document.body.innerHTML;
-
-	prep(function(){
-		html = html.replace(/id="test(\w).*?"/g, 'id="test$1' + num + '"');
-		html = html.replace(/name="test.*?"/g, 'name="test' + num + '"');
-		html = html.replace(/class="foo.*?"/g, 'class="foo test' + num + ' bar"');
-		var div = document.createElement("div");
-		div.innerHTML = html;
-		document.body.appendChild( div );
-	});
-
-	test( "getElementById", function(){
-		for ( var i = 0; i < num * 30; i++ ) {
-			ret = document.getElementById("testA" + num).nodeType;
-			ret = document.getElementById("testB" + num).nodeType;
-			ret = document.getElementById("testC" + num).nodeType;
-			ret = document.getElementById("testD" + num).nodeType;
-			ret = document.getElementById("testE" + num).nodeType;
-			ret = document.getElementById("testF" + num).nodeType;
-		}
-	});
-
-	test( "getElementById (not in document)", function(){
-		for ( var i = 0; i < num * 30; i++ ) {
-			ret = document.getElementById("testA");
-			ret = document.getElementById("testB");
-			ret = document.getElementById("testC");
-			ret = document.getElementById("testD");
-			ret = document.getElementById("testE");
-			ret = document.getElementById("testF");
-		}
-	});
-
-	test( "getElementsByTagName(div)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("div");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName(p)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("p");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName(a)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("a");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName(*)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("*");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName (not in document)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("strong");
-			ret = elems.length == 0;
-		}
-	});
-
-	test( "getElementsByName", function(){
-		for ( var i = 0; i < num * 20; i++ ) {
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByName (not in document)", function(){
-		for ( var i = 0; i < num * 20; i++ ) {
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-		}
-	});
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="testF10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2 id="testA10"><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
-
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2 id="testB10"><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2 id="testC10"><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2 id="testD10"><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2 id="testE10"><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators.
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment:
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element.
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element.
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML
-paragraph that will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag
-sequence. The other lines will be treated as
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt;
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt;
-S
-&lt;/P::first-letter&gt;ome text that
-&lt;/P::first-line&gt;
-ends up on two lines
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree.
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>:
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-
-<p>Selectors can be used in STTS 3 in two different
-    manners:
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification.
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-traverse-html.dart b/samples/third_party/dromaeo/web/tests/dom-traverse-html.dart
deleted file mode 100644
index 19fb3e5e..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-traverse-html.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import "dart:convert";
-import '../common/common.dart';
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-
-void main() {
-  final int num = 40;
-
-  // Try to force real results.
-  var ret;
-
-  String html = document.body.innerHtml;
-
-  new Suite(window, 'dom-traverse')
-    .prep(() {
-      html = BenchUtil.replaceAll(html, 'id="test(\\w).*?"', (Match match) {
-        final group = match.group(1);
-        return 'id="test${group}${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'name="test.*?"', (Match match) {
-        return 'name="test${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'class="foo.*?"', (Match match) {
-        return 'class="foo test${num} bar"';
-      });
-
-      final div = new Element.tag('div');
-      div.innerHtml = html;
-      document.body.append(div);
-    })
-    .test('firstChild', () {
-      final nodes = document.body.childNodes;
-      final nl = nodes.length;
-
-      for (int i = 0; i < num; i++) {
-        for (int j = 0; j < nl; j++) {
-          Node cur = nodes[j];
-          while (cur != null) {
-            cur = cur.firstChild;
-          }
-          ret = cur;
-        }
-      }
-    })
-    .test('lastChild', () {
-      final nodes = document.body.childNodes;
-      final nl = nodes.length;
-
-      for (int i = 0; i < num; i++) {
-        for (int j = 0; j < nl; j++) {
-          Node cur = nodes[j];
-          while (cur != null) {
-            cur = cur.lastChild;
-          }
-          ret = cur;
-        }
-      }
-    })
-    .test('nextSibling', () {
-      for (int i = 0; i < num * 2; i++) {
-        Node cur = document.body.firstChild;
-        while (cur != null) {
-          cur = cur.nextNode;
-        }
-        ret = cur;
-      }
-    })
-    .test('previousSibling', () {
-      for (int i = 0; i < num * 2; i++) {
-        Node cur = document.body.lastChild;
-        while (cur != null) {
-          cur = cur.previousNode;
-        }
-        ret = cur;
-      }
-    })
-    .test('childNodes', () {
-      for (int i = 0; i < num; i++) {
-        final nodes = document.body.childNodes;
-        for (int j = 0; j < nodes.length; j++) {
-          ret = nodes[j];
-        }
-      }
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-traverse-html.html b/samples/third_party/dromaeo/web/tests/dom-traverse-html.html
deleted file mode 100644
index ed13976..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-traverse-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-traverse-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-traverse.html b/samples/third_party/dromaeo/web/tests/dom-traverse.html
deleted file mode 100644
index 9b0a098..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-traverse.html
+++ /dev/null
@@ -1,2972 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-traverse");
-
-// Try to force real results
-var ret, tmp;
-var num = 40;
-var html = document.body.innerHTML;
-
-	prep(function(){
-		html = html.replace(/id="test.*?"/g, 'id="test' + num + '"');
-		html = html.replace(/name="test.*?"/g, 'name="test' + num + '"');
-		html = html.replace(/class="foo.*?"/g, 'class="foo test' + num + ' bar"');
-		var div = document.createElement("div");
-		div.innerHTML = html;
-		document.body.appendChild( div );
-	});
-
-	test( "firstChild", function(){
-		var nodes = document.body.childNodes, nl = nodes.length;
-
-		for ( var i = 0; i < num; i++ ) {
-			for ( var j = 0; j < nl; j++ ) {
-				var cur = nodes[j];
-				while ( cur )
-					cur = cur.firstChild;
-				ret = cur;
-			}
-		}
-	});
-
-	test( "lastChild", function(){
-		var nodes = document.body.childNodes, nl = nodes.length;
-
-		for ( var i = 0; i < num; i++ ) {
-			for ( var j = 0; j < nl; j++ ) {
-				var cur = nodes[j];
-				while ( cur )
-					cur = cur.lastChild;
-				ret = cur;
-			}
-		}
-	});
-
-	test( "nextSibling", function(){
-		for ( var i = 0; i < num * 2; i++ ) {
-			var cur = document.body.firstChild;
-			while ( cur )
-				cur = cur.nextSibling;
-			ret = cur;
-		}
-	});
-
-	test( "previousSibling", function(){
-		for ( var i = 0; i < num * 2; i++ ) {
-			var cur = document.body.lastChild;
-			while ( cur )
-				cur = cur.previousSibling;
-			ret = cur;
-		}
-	});
-
-	test( "childNodes", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var nodes = document.body.childNodes;
-			for ( var j = 0; j < nodes.length; j++ )
-				ret = nodes[j];
-		}
-	});
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
-
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators.
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment:
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element.
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element.
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML
-paragraph that will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag
-sequence. The other lines will be treated as
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt;
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt;
-S
-&lt;/P::first-letter&gt;ome text that
-&lt;/P::first-line&gt;
-ends up on two lines
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree.
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>:
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-
-<p>Selectors can be used in STTS 3 in two different
-    manners:
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification.
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/web-style.css b/samples/third_party/dromaeo/web/web-style.css
deleted file mode 100644
index c439dc0..0000000
--- a/samples/third_party/dromaeo/web/web-style.css
+++ /dev/null
@@ -1,24 +0,0 @@
-
-a { color: orange; }
-div.test { overflow: hidden; margin: 4px; }
-div.test b { display: block; float: left; width: 150px; text-align: right; margin-right: 10px; }
-div.bar { float: left; width: 400px; border: 1px inset; text-align: left; }
-div.bar div { height: 1em; background: url(orange-stripe.png); }
-div.bar span { padding-left: 5px; padding-right: 5px; }
-body { font-family: Arial; font-size: 12px; background: url(gray-stripe.png); text-align: center; }
-
-/*#main { margin: 0 auto; width: 600px; padding: 10px; background: #FFF; }*/
-
-ol.results { text-align: left; display: none; font-size: 10px; margin-left: 120px; list-style: none; }
-ol.results li { clear: both; overflow: auto; }
-ol.results b { display: block; width: 200px; float: left; text-align: right; padding-right: 15px; }
-#info, div.results { clear:both;width:420px;margin:10 auto;text-align:left; padding: 10px 10px 10px 110px; }
-#info span { background: #FFF; color: #000; padding: 8px 4px 4px 4px; }
-h1 { text-align: left; }
-h1 img { float:left;margin-right: 15px;margin-top: -10px; border: 0; }
-h1 small { font-weight:normal; }
-iframe { display: none; }
-div.resultwrap { text-align: center; }
-table.results { font-size: 12px; margin: 0 auto; }
-table.results td, table.results th.name { text-align: right; }
-table.results .winner { background-color: #c7331d; }
diff --git a/samples/third_party/todomvc_performance/.gitignore b/samples/third_party/todomvc_performance/.gitignore
deleted file mode 100644
index 378eac2..0000000
--- a/samples/third_party/todomvc_performance/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/samples/third_party/todomvc_performance/AUTHORS b/samples/third_party/todomvc_performance/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/LICENSE b/samples/third_party/todomvc_performance/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/PATENTS b/samples/third_party/todomvc_performance/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/README.md b/samples/third_party/todomvc_performance/README.md
deleted file mode 100644
index c7a053f..0000000
--- a/samples/third_party/todomvc_performance/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Polymer TodoMVC Performance Test
-
-This directory is a copy of samples/third_party/todomvc with some modifications
-to make a performance test and added a pure JS implementation for comparison.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/AUTHORS
deleted file mode 100755
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/CONTRIBUTING.md
deleted file mode 100755
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/LICENSE
deleted file mode 100755
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/PATENTS
deleted file mode 100755
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/README.md b/samples/third_party/todomvc_performance/js_todomvc/README.md
deleted file mode 100755
index da3d1bc..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-This is a snapshot of https://github.com/Polymer/todomvc taken on 3-14-14.
-
-# Polymer TodoMVC Example
-
-> Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.
-
-> _[Polymer - www.polymer-project.org](http://www.polymer-project.org/)_
-
-## Learning Polymer
-
-The [Polymer website](http://www.polymer-project.org) is a great resource for getting started.
-
-Here are some links you may find helpful:
-
-* [Getting Started](http://www.polymer-project.org/docs/start/everything.html)
-* [FAQ](http://www.polymer-project.org/resources/faq.html)
-* [Browser Compatibility](http://www.polymer-project.org/resources/compatibility.html)
-
-Get help from Polymer devs and users:
-
-* Find us on IRC on __#polymer__ at freenode.
-* Join the high-traffic [polymer-dev](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev) Google group or the announcement-only [polymer-announce](https://groups.google.com/forum/?fromgroups=#!forum/polymer-announce) Google group.
-
-## Implementation
-
-The Polymer implementation of TodoMVC has a few key differences with other implementations:
-
-* Since [Web Components](http://w3c.github.io/webcomponents/explainer/) allow you to create new types of DOM elements, the DOM tree is very different from other implementations.
-* The template, styling, and behavior are fully encapsulated in each custom element. Instead of having an overall stylesheet (`base.css` or `app.css`), each element that needs styling has its own stylesheet.
-* Non-visual elements such as the router and the model are also implemented as custom elements and appear in the DOM. Implementing them as custom elements instead of plain objects allows you to take advantage of Polymer data binding and event handling throughout the app.
-
-## Compatibility
-
-Polymer and its polyfills are intended to work in the latest version of [evergreen browsers](http://tomdale.net/2013/05/evergreen-browsers/). IE9 is not supported. Please refer to [Browser Compatibility](http://www.polymer-project.org/resources/compatibility.html) for more details.
-
-## Running this sample
-
-1. Install [node.js](nodejs.org) (required for `bower` client-side package management)
-1. Install bower: `npm install -g bower`
-
-1. From the `todomvc\` folder, run `bower update`
-1. Start a web server in the `todomvc\` folder.  Hint: if you have python installed, you can just run:
-
-     `python -m SimpleHTTPServer`
-
-1. Browse to the server root
diff --git a/samples/third_party/todomvc_performance/js_todomvc/app/app.css b/samples/third_party/todomvc_performance/js_todomvc/app/app.css
deleted file mode 100755
index 12f3666..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/app/app.css
+++ /dev/null
@@ -1,206 +0,0 @@
-/* base.css overrides */
-
-html,
-body {
-	margin: 0;
-	padding: 0;
-}
-
-body {
-	font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
-	line-height: 1.4em;
-	background: #eaeaea url('../components/todomvc-common/bg.png');
-	color: #4d4d4d;
-	width: 550px;
-	margin: 0 auto;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-body > header {
-  padding-top: 22px;
-  margin-bottom: -5px;
-}
-
-h1 {
-  /*	position: absolute;
-	top: -120px;*/
-	width: 100%;
-	font-size: 70px;
-	font-weight: bold;
-	text-align: center;
-	color: #b3b3b3;
-	color: rgba(255, 255, 255, 0.3);
-	text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-	-webkit-text-rendering: optimizeLegibility;
-	-moz-text-rendering: optimizeLegibility;
-	-ms-text-rendering: optimizeLegibility;
-	-o-text-rendering: optimizeLegibility;
-	text-rendering: optimizeLegibility;
-}
-
-#info {
-	margin: 65px auto 0;
-	color: #a6a6a6;
-	font-size: 12px;
-	text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-	text-align: center;
-}
-
-#info a {
-	color: inherit;
-}
-
-.hidden{
-	display:none;
-}
-
-hr {
-	margin: 20px 0;
-	border: 0;
-	border-top: 1px dashed #C5C5C5;
-	border-bottom: 1px dashed #F7F7F7;
-}
-
-.learn a {
-	font-weight: normal;
-	text-decoration: none;
-	color: #b83f45;
-}
-
-.learn a:hover {
-	text-decoration: underline;
-	color: #787e7e;
-}
-
-.learn h3,
-.learn h4,
-.learn h5 {
-	margin: 10px 0;
-	font-weight: 500;
-	line-height: 1.2;
-	color: #000;
-}
-
-.learn h3 {
-	font-size: 24px;
-}
-
-.learn h4 {
-	font-size: 18px;
-}
-
-.learn h5 {
-	margin-bottom: 0;
-	font-size: 14px;
-}
-
-.learn ul {
-	padding: 0;
-	margin: 0 0 30px 25px;
-}
-
-.learn li {
-	line-height: 20px;
-}
-
-.learn p {
-	font-size: 15px;
-	font-weight: 300;
-	line-height: 1.3;
-	margin-top: 0;
-	margin-bottom: 0;
-}
-
-.quote {
-	border: none;
-	margin: 20px 0 60px 0;
-}
-
-.quote p {
-	font-style: italic;
-}
-
-.quote p:before {
-	content: '“';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	top: -20px;
-	left: 3px;
-}
-
-.quote p:after {
-	content: '”';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	bottom: -42px;
-	right: 3px;
-}
-
-.quote footer {
-	position: absolute;
-	bottom: -40px;
-	right: 0;
-}
-
-.quote footer img {
-	border-radius: 3px;
-}
-
-.quote footer a {
-	margin-left: 5px;
-	vertical-align: middle;
-}
-
-.speech-bubble {
-	position: relative;
-	padding: 10px;
-	background: rgba(0, 0, 0, .04);
-	border-radius: 5px;
-}
-
-.speech-bubble:after {
-	content: '';
-	position: absolute;
-	top: 100%;
-	right: 30px;
-	border: 13px solid transparent;
-	border-top-color: rgba(0, 0, 0, .04);
-}
-
-/**body*/.learn-bar > .learn {
-	position: absolute;
-	width: 272px;
-	top: 8px;
-	left: -300px;
-	padding: 10px;
-	border-radius: 5px;
-	background-color: rgba(255, 255, 255, .6);
-	transition-property: left;
-	transition-duration: 500ms;
-}
-
-
-/* IE doesn't support the hidden attribute */
-[hidden] {
-	display: none;
-}
-
-@media (min-width: 899px) {
-	/**body*/.learn-bar {
-		width: auto;
-		margin: 0 0 0 300px;
-	}
-	/**body*/.learn-bar > .learn {
-		left: 8px;
-	}
-	/**body*/.learn-bar #todoapp {
-		width: 550px;
-		margin: 130px auto 40px auto;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/bower.json b/samples/third_party/todomvc_performance/js_todomvc/bower.json
deleted file mode 100755
index c67d0d1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/bower.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-	"name": "todomvc-template",
-	"version": "0.0.0",
-	"dependencies": {
-		"todomvc-common": "~0.1.4",
-    "polymer-selector": "Polymer/polymer-selector",
-    "flatiron-director": "Polymer/flatiron-director",
-    "polymer-localstorage": "Polymer/polymer-localstorage"
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/.bower.json
deleted file mode 100644
index f221bde..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/.bower.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "flatiron-director",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/flatiron-director",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "d01427ec016607908f939aad6b7ab4164b355a73"
-  },
-  "_source": "git://github.com/Polymer/flatiron-director.git",
-  "_target": "*",
-  "_originalSource": "Polymer/flatiron-director"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/LICENSE
deleted file mode 100644
index a9bb4eb..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011 Nodejitsu Inc.
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/bower.json
deleted file mode 100644
index f12cefa..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "name": "flatiron-director",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/demo.html
deleted file mode 100644
index ea77ba6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/demo.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>Director</title>
-    <script src="../platform/platform.js"></script>
-    <link rel="import" href="flatiron-director.html">
-  </head>
-  <body>
-    <polymer-element name="x-test">
-      <template>
-        <flatiron-director route="{{route}}" autoHash></flatiron-director>
-        hash: <input value="{{route}}">
-        <a href="#barnacle">Relocate</a>
-      </template>
-      <script>
-        Polymer('x-test', {
-          route: 'hello'
-        });
-      </script>
-    </polymer-element>
-    
-    <x-test></x-test>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/LICENSE
deleted file mode 100644
index 1f01e2b..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011 Nodejitsu Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/director.min.js b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/director.min.js
deleted file mode 100644
index 55a8e64..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/director.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-//
-// Generated on Fri Dec 27 2013 12:02:11 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon).
-// Version 1.2.2
-//
-(function(a){function k(a,b,c,d){var e=0,f=0,g=0,c=(c||"(").toString(),d=(d||")").toString(),h;for(h=0;h<a.length;h++){var i=a[h];if(i.indexOf(c,e)>i.indexOf(d,e)||~i.indexOf(c,e)&&!~i.indexOf(d,e)||!~i.indexOf(c,e)&&~i.indexOf(d,e)){f=i.indexOf(c,e),g=i.indexOf(d,e);if(~f&&!~g||!~f&&~g){var j=a.slice(0,(h||1)+1).join(b);a=[j].concat(a.slice((h||1)+1))}e=(g>f?g:f)+1,h=0}else e=0}return a}function j(a,b){var c,d=0,e="";while(c=a.substr(d).match(/[^\w\d\- %@&]*\*[^\w\d\- %@&]*/))d=c.index+c[0].length,c[0]=c[0].replace(/^\*/,"([_.()!\\ %@&a-zA-Z0-9-]+)"),e+=a.substr(0,c.index)+c[0];a=e+=a.substr(d);var f=a.match(/:([^\/]+)/ig),g,h;if(f){h=f.length;for(var j=0;j<h;j++)g=f[j],g.slice(0,2)==="::"?a=g.slice(1):a=a.replace(g,i(g,b))}return a}function i(a,b,c){c=a;for(var d in b)if(b.hasOwnProperty(d)){c=b[d](a);if(c!==a)break}return c===a?"([._a-zA-Z0-9-]+)":c}function h(a,b,c){if(!a.length)return c();var d=0;(function e(){b(a[d],function(b){b||b===!1?(c(b),c=function(){}):(d+=1,d===a.length?c():e())})})()}function g(a){var b=[];for(var c=0,d=a.length;c<d;c++)b=b.concat(a[c]);return b}function f(a,b){for(var c=0;c<a.length;c+=1)if(b(a[c],c,a)===!1)return}function c(){return b.hash===""||b.hash==="#"}Array.prototype.filter||(Array.prototype.filter=function(a,b){var c=[],d;for(var e=0,f=this.length;e<f;e++)e in this&&a.call(b,d=this[e],e,this)&&c.push(d);return c}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"});var b=document.location,d={mode:"modern",hash:b.hash,history:!1,check:function(){var a=b.hash;a!=this.hash&&(this.hash=a,this.onHashChanged())},fire:function(){this.mode==="modern"?this.history===!0?window.onpopstate():window.onhashchange():this.onHashChanged()},init:function(a,b){function d(a){for(var b=0,c=e.listeners.length;b<c;b++)e.listeners[b](a)}var c=this;this.history=b,e.listeners||(e.listeners=[]);if("onhashchange"in window&&(document.documentMode===undefined||document.documentMode>7))this.history===!0?setTimeout(function(){window.onpopstate=d},500):window.onhashchange=d,this.mode="modern";else{var f=document.createElement("iframe");f.id="state-frame",f.style.display="none",document.body.appendChild(f),this.writeFrame(""),"onpropertychange"in document&&"attachEvent"in document&&document.attachEvent("onpropertychange",function(){event.propertyName==="location"&&c.check()}),window.setInterval(function(){c.check()},50),this.onHashChanged=d,this.mode="legacy"}e.listeners.push(a);return this.mode},destroy:function(a){if(!!e&&!!e.listeners){var b=e.listeners;for(var c=b.length-1;c>=0;c--)b[c]===a&&b.splice(c,1)}},setHash:function(a){this.mode==="legacy"&&this.writeFrame(a),this.history===!0?(window.history.pushState({},document.title,a),this.fire()):b.hash=a[0]==="/"?a:"/"+a;return this},writeFrame:function(a){var b=document.getElementById("state-frame"),c=b.contentDocument||b.contentWindow.document;c.open(),c.write("<script>_hash = '"+a+"'; onload = parent.listener.syncHash;<script>"),c.close()},syncHash:function(){var a=this._hash;a!=b.hash&&(b.hash=a);return this},onHashChanged:function(){}},e=a.Router=function(a){if(this instanceof e)this.params={},this.routes={},this.methods=["on","once","after","before"],this.scope=[],this._methods={},this._insert=this.insert,this.insert=this.insertEx,this.historySupport=(window.history!=null?window.history.pushState:null)!=null,this.configure(),this.mount(a||{});else return new e(a)};e.prototype.init=function(a){var e=this;this.handler=function(a){var b=a&&a.newURL||window.location.hash,c=e.history===!0?e.getPath():b.replace(/.*#/,"");e.dispatch("on",c.charAt(0)==="/"?c:"/"+c)},d.init(this.handler,this.history);if(this.history===!1)c()&&a?b.hash=a:c()||e.dispatch("on","/"+b.hash.replace(/^(#\/|#|\/)/,""));else{var f=c()&&a?a:c()?null:b.hash.replace(/^#/,"");f&&window.history.replaceState({},document.title,f),(f||this.run_in_init===!0)&&this.handler()}return this},e.prototype.explode=function(){var a=this.history===!0?this.getPath():b.hash;a.charAt(1)==="/"&&(a=a.slice(1));return a.slice(1,a.length).split("/")},e.prototype.setRoute=function(a,b,c){var e=this.explode();typeof a=="number"&&typeof b=="string"?e[a]=b:typeof c=="string"?e.splice(a,b,s):e=[a],d.setHash(e.join("/"));return e},e.prototype.insertEx=function(a,b,c,d){a==="once"&&(a="on",c=function(a){var b=!1;return function(){if(!b){b=!0;return a.apply(this,arguments)}}}(c));return this._insert(a,b,c,d)},e.prototype.getRoute=function(a){var b=a;if(typeof a=="number")b=this.explode()[a];else if(typeof a=="string"){var c=this.explode();b=c.indexOf(a)}else b=this.explode();return b},e.prototype.destroy=function(){d.destroy(this.handler);return this},e.prototype.getPath=function(){var a=window.location.pathname;a.substr(0,1)!=="/"&&(a="/"+a);return a},e.prototype.configure=function(a){a=a||{};for(var b=0;b<this.methods.length;b++)this._methods[this.methods[b]]=!0;this.recurse=a.recurse||this.recurse||!1,this.async=a.async||!1,this.delimiter=a.delimiter||"/",this.strict=typeof a.strict=="undefined"?!0:a.strict,this.notfound=a.notfound,this.resource=a.resource,this.history=a.html5history&&this.historySupport||!1,this.run_in_init=this.history===!0&&a.run_handler_in_init!==!1,this.every={after:a.after||null,before:a.before||null,on:a.on||null};return this},e.prototype.param=function(a,b){a[0]!==":"&&(a=":"+a);var c=new RegExp(a,"g");this.params[a]=function(a){return a.replace(c,b.source||b)}},e.prototype.on=e.prototype.route=function(a,b,c){var d=this;!c&&typeof b=="function"&&(c=b,b=a,a="on");if(Array.isArray(b))return b.forEach(function(b){d.on(a,b,c)});b.source&&(b=b.source.replace(/\\\//ig,"/"));if(Array.isArray(a))return a.forEach(function(a){d.on(a.toLowerCase(),b,c)});b=b.split(new RegExp(this.delimiter)),b=k(b,this.delimiter),this.insert(a,this.scope.concat(b),c)},e.prototype.dispatch=function(a,b,c){function h(){d.last=e.after,d.invoke(d.runlist(e),d,c)}var d=this,e=this.traverse(a,b,this.routes,""),f=this._invoked,g;this._invoked=!0;if(!e||e.length===0){this.last=[],typeof this.notfound=="function"&&this.invoke([this.notfound],{method:a,path:b},c);return!1}this.recurse==="forward"&&(e=e.reverse()),g=this.every&&this.every.after?[this.every.after].concat(this.last):[this.last];if(g&&g.length>0&&f){this.async?this.invoke(g,this,h):(this.invoke(g,this),h());return!0}h();return!0},e.prototype.invoke=function(a,b,c){var d=this,e;this.async?(e=function(c,d){if(Array.isArray(c))return h(c,e,d);typeof c=="function"&&c.apply(b,a.captures.concat(d))},h(a,e,function(){c&&c.apply(b,arguments)})):(e=function(c){if(Array.isArray(c))return f(c,e);if(typeof c=="function")return c.apply(b,a.captures||[]);typeof c=="string"&&d.resource&&d.resource[c].apply(b,a.captures||[])},f(a,e))},e.prototype.traverse=function(a,b,c,d,e){function l(a){function c(a){for(var b=a.length-1;b>=0;b--)Array.isArray(a[b])?(c(a[b]),a[b].length===0&&a.splice(b,1)):e(a[b])||a.splice(b,1)}function b(a){var c=[];for(var d=0;d<a.length;d++)c[d]=Array.isArray(a[d])?b(a[d]):a[d];return c}if(!e)return a;var d=b(a);d.matched=a.matched,d.captures=a.captures,d.after=a.after.filter(e),c(d);return d}var f=[],g,h,i,j,k;if(b===this.delimiter&&c[a]){j=[[c.before,c[a]].filter(Boolean)],j.after=[c.after].filter(Boolean),j.matched=!0,j.captures=[];return l(j)}for(var m in c)if(c.hasOwnProperty(m)&&(!this._methods[m]||this._methods[m]&&typeof c[m]=="object"&&!Array.isArray(c[m]))){g=h=d+this.delimiter+m,this.strict||(h+="["+this.delimiter+"]?"),i=b.match(new RegExp("^"+h));if(!i)continue;if(i[0]&&i[0]==b&&c[m][a]){j=[[c[m].before,c[m][a]].filter(Boolean)],j.after=[c[m].after].filter(Boolean),j.matched=!0,j.captures=i.slice(1),this.recurse&&c===this.routes&&(j.push([c.before,c.on].filter(Boolean)),j.after=j.after.concat([c.after].filter(Boolean)));return l(j)}j=this.traverse(a,b,c[m],g);if(j.matched){j.length>0&&(f=f.concat(j)),this.recurse&&(f.push([c[m].before,c[m].on].filter(Boolean)),j.after=j.after.concat([c[m].after].filter(Boolean)),c===this.routes&&(f.push([c.before,c.on].filter(Boolean)),j.after=j.after.concat([c.after].filter(Boolean)))),f.matched=!0,f.captures=j.captures,f.after=j.after;return l(f)}}return!1},e.prototype.insert=function(a,b,c,d){var e,f,g,h,i;b=b.filter(function(a){return a&&a.length>0}),d=d||this.routes,i=b.shift(),/\:|\*/.test(i)&&!/\\d|\\w/.test(i)&&(i=j(i,this.params));if(b.length>0){d[i]=d[i]||{};return this.insert(a,b,c,d[i])}{if(!!i||!!b.length||d!==this.routes){f=typeof d[i],g=Array.isArray(d[i]);if(d[i]&&!g&&f=="object"){e=typeof d[i][a];switch(e){case"function":d[i][a]=[d[i][a],c];return;case"object":d[i][a].push(c);return;case"undefined":d[i][a]=c;return}}else if(f=="undefined"){h={},h[a]=c,d[i]=h;return}throw new Error("Invalid route context: "+f)}e=typeof d[a];switch(e){case"function":d[a]=[d[a],c];return;case"object":d[a].push(c);return;case"undefined":d[a]=c;return}}},e.prototype.extend=function(a){function e(a){b._methods[a]=!0,b[a]=function(){var c=arguments.length===1?[a,""]:[a];b.on.apply(b,c.concat(Array.prototype.slice.call(arguments)))}}var b=this,c=a.length,d;for(d=0;d<c;d++)e(a[d])},e.prototype.runlist=function(a){var b=this.every&&this.every.before?[this.every.before].concat(g(a)):g(a);this.every&&this.every.on&&b.push(this.every.on),b.captures=a.captures,b.source=a.source;return b},e.prototype.mount=function(a,b){function d(b,d){var e=b,f=b.split(c.delimiter),g=typeof a[b],h=f[0]===""||!c._methods[f[0]],i=h?"on":e;h&&(e=e.slice((e.match(new RegExp("^"+c.delimiter))||[""])[0].length),f.shift());h&&g==="object"&&!Array.isArray(a[b])?(d=d.concat(f),c.mount(a[b],d)):(h&&(d=d.concat(e.split(c.delimiter)),d=k(d,c.delimiter)),c.insert(i,d,a[b]))}if(!!a&&typeof a=="object"&&!Array.isArray(a)){var c=this;b=b||[],Array.isArray(b)||(b=b.split(c.delimiter));for(var e in a)a.hasOwnProperty(e)&&d(e,b.slice(0))}}})(typeof exports=="object"?exports:window)
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/flatiron-director.html b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/flatiron-director.html
deleted file mode 100644
index f0538cd..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/flatiron-director.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<link rel="import" href="../polymer/polymer.html">
-<script src="director/director.min.js"></script>
-
-<polymer-element name="flatiron-director" attributes="route autoHash">
-  <script>
-    (function() {
-      var private_router;
-      Polymer('flatiron-director', {
-        autoHash: false,
-        ready: function() {
-          this.router.on(/(.*)/, function(route) {
-            this.route = route;
-          }.bind(this));
-          this.route = this.router.getRoute(0) || '';
-        },
-        routeChanged: function() {
-          if (this.autoHash) {
-            window.location.hash = this.route;
-          }
-          this.fire('director-route', this.route);
-        },
-        get router() {
-          if (!private_router) {
-            private_router = new Router();
-            private_router.init();
-          }
-          return private_router;
-        }
-      });
-    })();
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/platform/.bower.json
deleted file mode 100644
index 6aa570e..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/.bower.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "name": "platform",
-  "main": "platform.js",
-  "homepage": "https://github.com/Polymer/platform",
-  "authors": [
-    "The Polymer Authors"
-  ],
-  "description": "Integrate platform polyfills: load, build, test",
-  "keywords": [
-    "polymer",
-    "web",
-    "components"
-  ],
-  "license": "BSD",
-  "private": true,
-  "version": "0.2.1",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "961d6f68848b9479d4d778466c37c0835837bc1c"
-  },
-  "_source": "git://github.com/Polymer/platform.git",
-  "_target": "0.2.1",
-  "_originalSource": "Polymer/platform"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/platform/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/platform/CONTRIBUTING.md
deleted file mode 100644
index 1de2f34..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/CONTRIBUTING.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Contributing
-
-Want to contribute to Polymer? Great!
-
-We are more than happy to accept external contributions to the project in the form of [feedback](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev), [bug reports](../../issues), and pull requests.
-
-## Contributor License Agreement
-
-Before we can accept patches, there's a quick web form you need to fill out.
-
-- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
-- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
-
-This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
-
-Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
-
-[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
-
-## Initial setup
-
-Here's an easy guide that should get you up and running:
-
-1. Setup Grunt: `sudo npm install -g grunt-cli`
-1. Fork the project on github and pull down your copy.
-   > replace the {{ username }} with your username and {{ repository }} with the repository name
-
-        git clone git@github.com:{{ username }}/{{ repository }}.git --recursive
-
-    Note the `--recursive`. This is necessary for submodules to initialize properly. If you don't do a recursive clone, you'll have to init them manually:
-
-        git submodule init
-        git submodule update
-
-    Download and run the `pull-all.sh` script to install the sibling dependencies.
-
-        git clone git://github.com/Polymer/tools.git && tools/bin/pull-all.sh
-
-1. Test your change
-   > in the repo you've made changes to, run the tests:
-
-        cd $REPO
-        npm install
-        grunt test
-
-1. Commit your code and make a pull request.
-
-That's it for the one time setup. Now you're ready to make a change.
-
-## Submitting a pull request
-
-We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
-
-    git remote add upstream git://github.com/Polymer/{{ repository }}.git
-
-Then before making a change, do a pull from the upstream `master` branch:
-
-    git pull upstream master
-
-To make life easier, add a "pull upstream" alias in your `.gitconfig`:
-
-    [alias]
-      pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
-
-That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
-
-    git checkout master
-    git pu
-    # make change
-    git commit -a -m 'Awesome things.'
-    git push
-
-Lastly, don't forget to submit the pull request.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/platform/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/components/platform/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/platform/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/README.md b/samples/third_party/todomvc_performance/js_todomvc/components/platform/README.md
deleted file mode 100644
index 65b661e..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Platform
-========
-
-Aggregated polyfills the Polymer platform. 
-
-[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/platform/README)](https://github.com/igrigorik/ga-beacon)
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/platform/bower.json
deleted file mode 100644
index cc029b9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/bower.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "name": "platform",
-  "main": "platform.js",
-  "homepage": "https://github.com/Polymer/platform",
-  "authors": [
-    "The Polymer Authors"
-  ],
-  "description": "Integrate platform polyfills: load, build, test",
-  "keywords": [
-    "polymer",
-    "web",
-    "components"
-  ],
-  "license": "BSD",
-  "private": true,
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js b/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js
deleted file mode 100644
index 57f1b10..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @license
- * Copyright (c) 2012-2014 The Polymer 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.
- */
-// @version: 0.2.1
-function PointerGestureEvent(a,b){var c=b||{},d=document.createEvent("Event"),e={bubbles:Boolean(c.bubbles)===c.bubbles||!0,cancelable:Boolean(c.cancelable)===c.cancelable||!0};d.initEvent(a,e.bubbles,e.cancelable);for(var f,g=Object.keys(c),h=0;h<g.length;h++)f=g[h],d[f]=c[f];return d.preventTap=this.preventTap,d}"undefined"==typeof WeakMap&&!function(){var a=Object.defineProperty,b=Date.now()%1e9,c=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")};c.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}},window.WeakMap=c}(),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={};if(Object.observe(c,a),c.id=1,c.id=2,delete c.id,Object.deliverChangeRecords(a),3!==b.length)return!1;if("new"==b[0].type&&"updated"==b[1].type&&"deleted"==b[2].type)L="new",M="updated",N="reconfigured",O="deleted";else if("add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type)return console.error("Unexpected change record names for Object.observe. Using dirty-checking instead"),!1;return Object.unobserve(c,a),c=[0],Array.observe(c,a),c[1]=1,c.length=0,Object.deliverChangeRecords(a),2!=b.length?!1:b[0].type!=P||b[1].type!=P?!1:(Array.unobserve(c,a),!0)}function c(){if(a.document&&"securityPolicy"in a.document&&!a.document.securityPolicy.allowsEval)return!1;try{var b=new Function("","return true;");return b()}catch(c){return!1}}function d(a){return+a===a>>>0}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:S(a)&&S(b)?!0:a!==a&&b!==b}function h(a){return"string"!=typeof a?!1:(a=a.trim(),""==a?!0:"."==a[0]?!1:$.test(a))}function i(a,b){if(b!==_)throw Error("Use Path.get to retrieve path objects");return""==a.trim()?this:d(a)?(this.push(a),this):(a.split(/\s*\.\s*/).filter(function(a){return a}).forEach(function(a){this.push(a)},this),void(R&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn())))}function j(a){if(a instanceof i)return a;null==a&&(a=""),"string"!=typeof a&&(a=String(a));var b=ab[a];if(b)return b;if(!h(a))return bb;var b=new i(a,_);return ab[a]=b,b}function k(b){for(var c=0;db>c&&b.check_();)c++;return a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=c),c>0}function l(a){for(var b in a)return!1;return!0}function m(a){return l(a.added)&&l(a.removed)&&l(a.changed)}function n(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function o(){if(!eb.length)return!1;for(var a=0;a<eb.length;a++)eb[a]();return eb.length=0,!0}function p(){function a(a){b&&b.state_===kb&&!d&&b.check_(a)}var b,c,d=!1,e=!0;return{open:function(c){if(b)throw Error("ObservedObject in use");e||Object.deliverChangeRecords(a),b=c,e=!1},observe:function(b,d){c=b,d?Array.observe(c,a):Object.observe(c,a)},deliver:function(b){d=b,Object.deliverChangeRecords(a),d=!1},close:function(){b=void 0,Object.unobserve(c,a),gb.push(this)}}}function q(a,b,c){var d=gb.pop()||p();return d.open(a),d.observe(b,c),d}function r(){function a(b){if(f(b)){var c=j.indexOf(b);c>=0?(j[c]=void 0,i.push(b)):i.indexOf(b)<0&&(i.push(b),Object.observe(b,e)),a(Object.getPrototypeOf(b))}}function b(){var b=j===hb?[]:j;j=i,i=b;var c;for(var d in g)c=g[d],c&&c.state_==kb&&c.iterateObjects_(a);for(var f=0;f<j.length;f++){var h=j[f];h&&Object.unobserve(h,e)}j.length=0}function c(){l=!1,k&&b()}function d(){l||(k=!0,l=!0,fb(c))}function e(){b();var a;for(var c in g)a=g[c],a&&a.state_==kb&&a.check_()}var g=[],h=0,i=[],j=hb,k=!1,l=!1,m={object:void 0,objects:i,open:function(b){g[b.id_]=b,h++,b.iterateObjects_(a)},close:function(a){if(g[a.id_]=void 0,h--,h)return void d();k=!1;for(var b=0;b<i.length;b++)Object.unobserve(i[b],e),t.unobservedCount++;g.length=0,i.length=0,ib.push(this)},reset:d};return m}function s(a,b){return cb&&cb.object===b||(cb=ib.pop()||r(),cb.object=b),cb.open(a),cb}function t(){this.state_=jb,this.callback_=void 0,this.target_=void 0,this.directObserver_=void 0,this.value_=void 0,this.id_=nb++}function u(a){t._allObserversCount++,pb&&ob.push(a)}function v(){t._allObserversCount--}function w(a){t.call(this),this.value_=a,this.oldObject_=void 0}function x(a){if(!Array.isArray(a))throw Error("Provided object is not an Array");w.call(this,a)}function y(a,b){t.call(this),this.object_=a,this.path_=b instanceof i?b:j(b),this.directObserver_=void 0}function z(){t.call(this),this.value_=[],this.directObserver_=void 0,this.observed_=[]}function A(a){return a}function B(a,b,c,d){this.callback_=void 0,this.target_=void 0,this.value_=void 0,this.observable_=a,this.getValueFn_=b||A,this.setValueFn_=c||A,this.dontPassThroughSet_=d}function C(a,b){if("function"==typeof Object.observe){var c=Object.getNotifier(a);return function(d,e){var f={object:a,type:d,name:b};2===arguments.length&&(f.oldValue=e),c.notify(f)}}}function D(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];tb[g.type]?(g.name in c||(c[g.name]=g.oldValue),g.type!=M&&(g.type!=L?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function E(a,b,c){return{index:a,removed:b,addedCount:c}}function F(){}function G(a,b,c,d,e,f){return yb.calcSplices(a,b,c,d,e,f)}function H(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function I(a,b,c,d){for(var e=E(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=H(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function J(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case P:I(c,g.index,g.removed.slice(),g.addedCount);break;case L:case M:case O:if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;I(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function K(a,b){var c=[];return J(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?void(b.removed[0]!==a[b.index]&&c.push(b)):void(c=c.concat(G(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)))}),c}var L="add",M="update",N="reconfigure",O="delete",P="splice",Q=b(),R=c(),S=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},T="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},U="[$_a-zA-Z]",V="[$_a-zA-Z0-9]",W=U+"+"+V+"*",X="(?:[0-9]|[1-9]+[0-9]+)",Y="(?:"+W+"|"+X+")",Z="(?:"+Y+")(?:\\s*\\.\\s*"+Y+")*",$=new RegExp("^"+Z+"$"),_={},ab={};i.get=j,i.prototype=T({__proto__:[],valid:!0,toString:function(){return this.join(".")},getValueFrom:function(a){for(var b=0;b<this.length;b++){if(null==a)return;a=a[this[b]]}return a},iterateObjects:function(a,b){for(var c=0;c<this.length;c++){if(c&&(a=a[this[c-1]]),!a)return;b(a)}},compiledGetValueFromFn:function(){var a=this.map(function(a){return d(a)?'["'+a+'"]':"."+a}),b="",c="obj";b+="if (obj != null";for(var e=0;e<this.length-1;e++){{this[e]}c+=a[e],b+=" &&\n     "+c+" != null"}return b+=")\n",c+=a[e],b+="  return "+c+";\nelse\n  return undefined;",new Function("obj",b)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var bb=new i("",_);bb.valid=!1,bb.getValueFrom=bb.setValueFrom=function(){};var cb,db=1e3,eb=[],fb=Q?function(){var a={pingPong:!0},b=!1;return Object.observe(a,function(){o(),b=!1}),function(c){eb.push(c),b||(b=!0,a.pingPong=!a.pingPong)}}():function(){return function(a){eb.push(a)}}(),gb=[],hb=[],ib=[],jb=0,kb=1,lb=2,mb=3,nb=1;t.prototype={open:function(a,b){if(this.state_!=jb)throw Error("Observer has already been opened.");return u(this),this.callback_=a,this.target_=b,this.state_=kb,this.connect_(),this.value_},close:function(){this.state_==kb&&(v(this),this.state_=lb,this.disconnect_(),this.value_=void 0,this.callback_=void 0,this.target_=void 0)},deliver:function(){this.state_==kb&&k(this)},report_:function(a){try{this.callback_.apply(this.target_,a)}catch(b){t._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},discardChanges:function(){return this.check_(void 0,!0),this.value_}};var ob,pb=!Q;t._allObserversCount=0,pb&&(ob=[]);var qb=!1,rb="function"==typeof Object.deliverAllChangeRecords;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!qb){if(rb)return void Object.deliverAllChangeRecords();if(pb){qb=!0;var b,c,d=0;do{d++,c=ob,ob=[],b=!1;for(var e=0;e<c.length;e++){var f=c[e];f.state_==kb&&(f.check_()&&(b=!0),ob.push(f))}o()&&(b=!0)}while(db>d&&b);a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=d),qb=!1}}},pb&&(a.Platform.clearObservers=function(){ob=[]}),w.prototype=T({__proto__:t.prototype,arrayObserve:!1,connect_:function(){Q?this.directObserver_=q(this,this.value_,this.arrayObserve):this.oldObject_=this.copyObject(this.value_)},copyObject:function(a){var b=Array.isArray(a)?[]:{};for(var c in a)b[c]=a[c];return Array.isArray(a)&&(b.length=a.length),b},check_:function(a){var b,c;if(Q){if(!a)return!1;c={},b=D(this.value_,a,c)}else c=this.oldObject_,b=n(this.value_,this.oldObject_);return m(b)?!1:(Q||(this.oldObject_=this.copyObject(this.value_)),this.report_([b.added||{},b.removed||{},b.changed||{},function(a){return c[a]}]),!0)},disconnect_:function(){Q?(this.directObserver_.close(),this.directObserver_=void 0):this.oldObject_=void 0},deliver:function(){this.state_==kb&&(Q?this.directObserver_.deliver(!1):k(this))},discardChanges:function(){return this.directObserver_?this.directObserver_.deliver(!0):this.oldObject_=this.copyObject(this.value_),this.value_}}),x.prototype=T({__proto__:w.prototype,arrayObserve:!0,copyObject:function(a){return a.slice()},check_:function(a){var b;if(Q){if(!a)return!1;b=K(this.value_,a)}else b=G(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length);return b&&b.length?(Q||(this.oldObject_=this.copyObject(this.value_)),this.report_([b]),!0):!1}}),x.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})},y.prototype=T({__proto__:t.prototype,connect_:function(){Q&&(this.directObserver_=s(this,this.object_)),this.check_(void 0,!0)},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},iterateObjects_:function(a){this.path_.iterateObjects(this.object_,a)},check_:function(a,b){var c=this.value_;return this.value_=this.path_.getValueFrom(this.object_),b||g(this.value_,c)?!1:(this.report_([this.value_,c]),!0)},setValue:function(a){this.path_&&this.path_.setValueFrom(this.object_,a)}});var sb={};z.prototype=T({__proto__:t.prototype,connect_:function(){if(this.check_(void 0,!0),Q){for(var a,b=!1,c=0;c<this.observed_.length;c+=2)if(a=this.observed_[c],a!==sb){b=!0;break}return this.directObserver_?b?void this.directObserver_.reset():(this.directObserver_.close(),void(this.directObserver_=void 0)):void(b&&(this.directObserver_=s(this,a)))}},closeObservers_:function(){for(var a=0;a<this.observed_.length;a+=2)this.observed_[a]===sb&&this.observed_[a+1].close();this.observed_.length=0},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0),this.closeObservers_()},addPath:function(a,b){if(this.state_!=jb&&this.state_!=mb)throw Error("Cannot add paths once started.");this.observed_.push(a,b instanceof i?b:j(b))},addObserver:function(a){if(this.state_!=jb&&this.state_!=mb)throw Error("Cannot add observers once started.");a.open(this.deliver,this),this.observed_.push(sb,a)},startReset:function(){if(this.state_!=kb)throw Error("Can only reset while open");this.state_=mb,this.closeObservers_()},finishReset:function(){if(this.state_!=mb)throw Error("Can only finishReset after startReset");return this.state_=kb,this.connect_(),this.value_},iterateObjects_:function(a){for(var b,c=0;c<this.observed_.length;c+=2)b=this.observed_[c],b!==sb&&this.observed_[c+1].iterateObjects(b,a)},check_:function(a,b){for(var c,d=0;d<this.observed_.length;d+=2){var e=this.observed_[d+1],f=this.observed_[d],h=f===sb?e.discardChanges():e.getValueFrom(f);b?this.value_[d/2]=h:g(h,this.value_[d/2])||(c=c||[],c[d/2]=this.value_[d/2],this.value_[d/2]=h)}return c?(this.report_([this.value_,c,this.observed_]),!0):!1}}),B.prototype={open:function(a,b){return this.callback_=a,this.target_=b,this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this)),this.value_},observedCallback_:function(a){if(a=this.getValueFn_(a),!g(a,this.value_)){var b=this.value_;this.value_=a,this.callback_.call(this.target_,this.value_,b)}},discardChanges:function(){return this.value_=this.getValueFn_(this.observable_.discardChanges()),this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(a){return a=this.setValueFn_(a),!this.dontPassThroughSet_&&this.observable_.setValue?this.observable_.setValue(a):void 0},close:function(){this.observable_&&this.observable_.close(),this.callback_=void 0,this.target_=void 0,this.observable_=void 0,this.value_=void 0,this.getValueFn_=void 0,this.setValueFn_=void 0}};var tb={};tb[L]=!0,tb[M]=!0,tb[O]=!0,t.defineComputedProperty=function(a,b,c){var d=C(a,b),e=c.open(function(a,b){e=a,d&&d(M,b)});return Object.defineProperty(a,b,{get:function(){return c.deliver(),e},set:function(a){return c.setValue(a),a},configurable:!0}),{close:function(){c.close(),Object.defineProperty(a,b,{value:e,writable:!0,configurable:!0})}}};var ub=0,vb=1,wb=2,xb=3;F.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(ub):(e.push(vb),d=g),b--,c--):f==h?(e.push(xb),b--,d=h):(e.push(wb),c--,d=i)}else e.push(xb),b--;else e.push(wb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=E(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[E(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case ub:j&&(l.push(j),j=void 0),m++,n++;break;case vb:j||(j=E(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case wb:j||(j=E(m,[],0)),j.addedCount++,m++;break;case xb:j||(j=E(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var yb=new F;a.Observer=t,a.Observer.runEOM_=fb,a.Observer.hasObjectObserve=Q,a.ArrayObserver=x,a.ArrayObserver.calculateSplices=function(a,b){return yb.calculateSplices(a,b)},a.ArraySplice=F,a.ObjectObserver=w,a.PathObserver=y,a.CompoundObserver=z,a.Path=i,a.ObserverTransform=B,a.Observer.changeRecordTypes={add:L,update:M,reconfigure:N,"delete":O,splice:P}}("undefined"!=typeof global&&global&&"undefined"!=typeof module&&module?global:this||window),window.Platform=window.Platform||{},window.logFlags=window.logFlags||{},function(a){var b=a.flags||{};location.search.slice(1).split("&").forEach(function(a){a=a.split("="),a[0]&&(b[a[0]]=a[1]||!0)});var c=document.currentScript||document.querySelector('script[src*="platform.js"]');if(c)for(var d,e=c.attributes,f=0;f<e.length;f++)d=e[f],"src"!==d.name&&(b[d.name]=d.value||!0);b.log&&b.log.split(",").forEach(function(a){window.logFlags[a]=!0}),b.shadow=b.shadow||b.shadowdom||b.polyfill,b.shadow="native"===b.shadow?!1:b.shadow||!HTMLElement.prototype.createShadowRoot,b.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=b.register),b.imports&&(window.HTMLImports=window.HTMLImports||{flags:{}},window.HTMLImports.flags.imports=b.imports),a.flags=b}(Platform),Platform.flags.shadow?(window.ShadowDOMPolyfill={},function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a,b){return L(b).forEach(function(c){K(a,c,M(b,c))}),a}function d(a,b){return L(b).forEach(function(c){switch(c){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":return}K(a,c,M(b,c))}),a}function e(a,b){for(var c=0;c<b.length;c++)if(b[c]in a)return b[c]}function f(a){var b=a.__proto__||Object.getPrototypeOf(a),c=E.get(b);if(c)return c;var d=f(b),e=t(d);return q(b,e,a),e}function g(a,b){o(a,b,!0)}function h(a,b){o(b,a,!1)}function i(a){return/^on[a-z]+$/.test(a)}function j(a){return/^\w[a-zA-Z_0-9]*$/.test(a)}function k(a){return H&&j(a)?new Function("return this.impl."+a):function(){return this.impl[a]}}function l(a){return H&&j(a)?new Function("v","this.impl."+a+" = v"):function(b){this.impl[a]=b}}function m(a){return H&&j(a)?new Function("return this.impl."+a+".apply(this.impl, arguments)"):function(){return this.impl[a].apply(this.impl,arguments)}}function n(a,b){try{return Object.getOwnPropertyDescriptor(a,b)}catch(c){return O}}function o(b,c,d){for(var e=L(b),f=0;f<e.length;f++){var g=e[f];if("polymerBlackList_"!==g&&!(g in c||b.polymerBlackList_&&b.polymerBlackList_[g])){N&&b.__lookupGetter__(g);var h,j,o=n(b,g);if(d&&"function"==typeof o.value)c[g]=m(g);else{var p=i(g);h=p?a.getEventHandlerGetter(g):k(g),(o.writable||o.set)&&(j=p?a.getEventHandlerSetter(g):l(g)),K(c,g,{get:h,set:j,configurable:o.configurable,enumerable:o.enumerable})}}}}function p(a,b,c){var e=a.prototype;q(e,b,c),d(b,a)}function q(a,c,d){var e=c.prototype;b(void 0===E.get(a)),E.set(a,c),F.set(e,a),g(a,e),d&&h(e,d),K(e,"constructor",{value:c,configurable:!0,enumerable:!1,writable:!0}),c.prototype=e}function r(a,b){return E.get(b.prototype)===a}function s(a){var b=Object.getPrototypeOf(a),c=f(b),d=t(c);return q(b,d,a),d}function t(a){function b(b){a.call(this,b)}var c=Object.create(a.prototype);return c.constructor=b,b.prototype=c,b}function u(a){return a instanceof G.EventTarget||a instanceof G.Event||a instanceof G.Range||a instanceof G.DOMImplementation||a instanceof G.CanvasRenderingContext2D||G.WebGLRenderingContext&&a instanceof G.WebGLRenderingContext}function v(a){return Q&&a instanceof Q||a instanceof S||a instanceof R||a instanceof T||a instanceof U||a instanceof P||a instanceof V||W&&a instanceof W||X&&a instanceof X}function w(a){return null===a?null:(b(v(a)),a.polymerWrapper_||(a.polymerWrapper_=new(f(a))(a)))}function x(a){return null===a?null:(b(u(a)),a.impl)}function y(a){return a&&u(a)?x(a):a}function z(a){return a&&!u(a)?w(a):a}function A(a,c){null!==c&&(b(v(a)),b(void 0===c||u(c)),a.polymerWrapper_=c)}function B(a,b,c){K(a.prototype,b,{get:c,configurable:!0,enumerable:!0})}function C(a,b){B(a,b,function(){return w(this.impl[b])})}function D(a,b){a.forEach(function(a){b.forEach(function(b){a.prototype[b]=function(){var a=z(this);return a[b].apply(a,arguments)}})})}var E=new WeakMap,F=new WeakMap,G=Object.create(null),H=!("securityPolicy"in document)||document.securityPolicy.allowsEval;if(H)try{var I=new Function("","return true;");H=I()}catch(J){H=!1}var K=Object.defineProperty,L=Object.getOwnPropertyNames,M=Object.getOwnPropertyDescriptor;L(window);var N=/Firefox/.test(navigator.userAgent),O={get:function(){},set:function(){},configurable:!0,enumerable:!0},P=window.DOMImplementation,Q=window.EventTarget,R=window.Event,S=window.Node,T=window.Window,U=window.Range,V=window.CanvasRenderingContext2D,W=window.WebGLRenderingContext,X=window.SVGElementInstance;a.assert=b,a.constructorTable=E,a.defineGetter=B,a.defineWrapGetter=C,a.forwardMethodsToWrapper=D,a.isWrapper=u,a.isWrapperFor=r,a.mixin=c,a.nativePrototypeTable=F,a.oneOf=e,a.registerObject=s,a.registerWrapper=p,a.rewrap=A,a.unwrap=x,a.unwrapIfNeeded=y,a.wrap=w,a.wrapIfNeeded=z,a.wrappers=G}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){g=!1;var a=f.slice(0);f=[];for(var b=0;b<a.length;b++)a[b]()}function c(a){f.push(a),g||(g=!0,d(b,0))}var d,e=window.MutationObserver,f=[],g=!1;if(e){var h=1,i=new e(b),j=document.createTextNode(h);i.observe(j,{characterData:!0}),d=function(){h=(h+1)%2,j.data=h}}else d=window.setImmediate||window.setTimeout;a.setEndOfMicrotask=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){p||(k(c),p=!0)}function c(){p=!1;do for(var a=o.slice(),b=!1,c=0;c<a.length;c++){var d=a[c],e=d.takeRecords();f(d),e.length&&(d.callback_(e,d),b=!0)}while(b)}function d(a,b){this.type=a,this.target=b,this.addedNodes=new m.NodeList,this.removedNodes=new m.NodeList,this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function e(a,b){for(;a;a=a.parentNode){var c=n.get(a);if(c)for(var d=0;d<c.length;d++){var e=c[d];e.options.subtree&&e.addTransientObserver(b)}}}function f(a){for(var b=0;b<a.nodes_.length;b++){var c=a.nodes_[b],d=n.get(c);if(!d)return;for(var e=0;e<d.length;e++){var f=d[e];f.observer===a&&f.removeTransientObservers()}}}function g(a,c,e){for(var f=Object.create(null),g=Object.create(null),h=a;h;h=h.parentNode){var i=n.get(h);if(i)for(var j=0;j<i.length;j++){var k=i[j],l=k.options;if((h===a||l.subtree)&&!("attributes"===c&&!l.attributes||"attributes"===c&&l.attributeFilter&&(null!==e.namespace||-1===l.attributeFilter.indexOf(e.name))||"characterData"===c&&!l.characterData||"childList"===c&&!l.childList)){var m=k.observer;f[m.uid_]=m,("attributes"===c&&l.attributeOldValue||"characterData"===c&&l.characterDataOldValue)&&(g[m.uid_]=e.oldValue)}}}var o=!1;for(var p in f){var m=f[p],q=new d(c,a);"name"in e&&"namespace"in e&&(q.attributeName=e.name,q.attributeNamespace=e.namespace),e.addedNodes&&(q.addedNodes=e.addedNodes),e.removedNodes&&(q.removedNodes=e.removedNodes),e.previousSibling&&(q.previousSibling=e.previousSibling),e.nextSibling&&(q.nextSibling=e.nextSibling),void 0!==g[p]&&(q.oldValue=g[p]),m.records_.push(q),o=!0}o&&b()}function h(a){if(this.childList=!!a.childList,this.subtree=!!a.subtree,this.attributes="attributes"in a||!("attributeOldValue"in a||"attributeFilter"in a)?!!a.attributes:!0,this.characterData="characterDataOldValue"in a&&!("characterData"in a)?!0:!!a.characterData,!this.attributes&&(a.attributeOldValue||"attributeFilter"in a)||!this.characterData&&a.characterDataOldValue)throw new TypeError;if(this.characterData=!!a.characterData,this.attributeOldValue=!!a.attributeOldValue,this.characterDataOldValue=!!a.characterDataOldValue,"attributeFilter"in a){if(null==a.attributeFilter||"object"!=typeof a.attributeFilter)throw new TypeError;this.attributeFilter=q.call(a.attributeFilter)}else this.attributeFilter=null}function i(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++r,o.push(this)}function j(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var k=a.setEndOfMicrotask,l=a.wrapIfNeeded,m=a.wrappers,n=new WeakMap,o=[],p=!1,q=Array.prototype.slice,r=0;i.prototype={observe:function(a,b){a=l(a);var c,d=new h(b),e=n.get(a);e||n.set(a,e=[]);for(var f=0;f<e.length;f++)e[f].observer===this&&(c=e[f],c.removeTransientObservers(),c.options=d);c||(c=new j(this,a,d),e.push(c),this.nodes_.push(a))},disconnect:function(){this.nodes_.forEach(function(a){for(var b=n.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}},j.prototype={addTransientObserver:function(a){if(a!==this.target){this.transientObservedNodes.push(a);var b=n.get(a);b||n.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[];for(var b=0;b<a.length;b++)for(var c=a[b],d=n.get(c),e=0;e<d.length;e++)if(d[e]===this){d.splice(e,1);break}}},a.enqueueMutation=g,a.registerTransientObservers=e,a.wrappers.MutationObserver=i,a.wrappers.MutationRecord=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){this.root=a,this.parent=b}function c(a,b){if(a.treeScope_!==b){a.treeScope_=b;for(var d=a.firstChild;d;d=d.nextSibling)c(d,b)}}function d(a){if(a.treeScope_)return a.treeScope_;var c,e=a.parentNode;return c=e?d(e):new b(a,null),a.treeScope_=c}b.prototype={get renderer(){return this.root instanceof a.wrappers.ShadowRoot?a.getRendererForHost(this.root.host):null},contains:function(a){for(;a;a=a.parent)if(a===this)return!0;return!1}},a.TreeScope=b,a.getTreeScope=d,a.setTreeScope=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a instanceof P.ShadowRoot}function c(a){var b=a.localName;return"content"===b||"shadow"===b}function d(a){return!!a.shadowRoot}function e(a){var b;return a.parentNode||(b=a.defaultView)&&O(b)||null}function f(f,g,h){if(h.length)return h.shift();if(b(f))return j(f)||f.host;var i=a.eventParentsTable.get(f);if(i){for(var k=1;k<i.length;k++)h[k-1]=i[k];return i[0]}if(g&&c(f)){var l=f.parentNode;if(l&&d(l))for(var m=a.getShadowTrees(l),n=j(g),k=0;k<m.length;k++)if(m[k].contains(n))return n}return e(f)}function g(a){for(var d=[],e=a,g=[],i=[];e;){var j=null;if(c(e)){j=h(d);var k=d[d.length-1]||e;d.push(k)}else d.length||d.push(e);var l=d[d.length-1];g.push({target:l,currentTarget:e}),b(e)&&d.pop(),e=f(e,j,i)}return g}function h(a){for(var b=a.length-1;b>=0;b--)if(!c(a[b]))return a[b];return null}function i(a,d){for(var e=[];a;){for(var g=[],i=d,j=void 0;i;){var m=null;if(g.length){if(c(i)&&(m=h(g),k(j))){var n=g[g.length-1];g.push(n)}}else g.push(i);if(l(i,a))return g[g.length-1];b(i)&&g.pop(),j=i,i=f(i,m,e)}a=b(a)?a.host:a.parentNode}}function j(b){return a.insertionParentTable.get(b)}function k(a){return j(a)}function l(a,b){return K(a)===K(b)}function m(a){return R.get(a)?void 0:(R.set(a,!0),n(O(a),O(a.target)))}function n(b,c){if(S.get(b))throw new Error("InvalidStateError");S.set(b,!0),a.renderAllPending();var d=g(c);return"load"===b.type&&2===d.length&&d[0].target instanceof P.Document&&d.shift(),$.set(b,d),o(b,d)&&p(b,d)&&q(b,d),W.set(b,t.NONE),U.delete(b,null),S.delete(b),b.defaultPrevented}function o(a,b){for(var c,d=b.length-1;d>0;d--){var e=b[d].target,f=b[d].currentTarget;if(e!==f&&(c=t.CAPTURING_PHASE,!r(b[d],a,c)))return!1}return!0}function p(a,b){var c=t.AT_TARGET;return r(b[0],a,c)}function q(a,b){for(var c,d=a.bubbles,e=1;e<b.length;e++){var f=b[e].target,g=b[e].currentTarget;if(f===g)c=t.AT_TARGET;else{if(!d||Y.get(a))continue;c=t.BUBBLING_PHASE}if(!r(b[e],a,c))return}}function r(a,b,c){var d=a.target,e=a.currentTarget,f=Q.get(e);if(!f)return!0;if("relatedTarget"in b){var g=N(b);if(g.relatedTarget){var h=O(g.relatedTarget),j=i(e,h);if(j===d)return!0;V.set(b,j)}}W.set(b,c);var k=b.type,l=!1;T.set(b,d),U.set(b,e);for(var m=0;m<f.length;m++){var n=f[m];if(n.removed)l=!0;else if(!(n.type!==k||!n.capture&&c===t.CAPTURING_PHASE||n.capture&&c===t.BUBBLING_PHASE))try{if("function"==typeof n.handler?n.handler.call(e,b):n.handler.handleEvent(b),Y.get(b))return!1}catch(o){window.onerror?window.onerror(o.message):console.error(o,o.stack)}}if(l){var p=f.slice();f.length=0;for(var m=0;m<p.length;m++)p[m].removed||f.push(p[m])}return!X.get(b)}function s(a,b,c){this.type=a,this.handler=b,this.capture=Boolean(c)}function t(a,b){return a instanceof _?void(this.impl=a):O(x(_,"Event",a,b))}function u(a){return a&&a.relatedTarget?Object.create(a,{relatedTarget:{value:N(a.relatedTarget)}}):a}function v(a,b,c){var d=window[a],e=function(b,c){return b instanceof d?void(this.impl=b):O(x(d,a,b,c))};if(e.prototype=Object.create(b.prototype),c&&L(e.prototype,c),d)try{M(d,e,new d("temp"))}catch(f){M(d,e,document.createEvent(a))}return e}function w(a,b){return function(){arguments[b]=N(arguments[b]);var c=N(this);c[a].apply(c,arguments)}}function x(a,b,c,d){if(ib)return new a(c,u(d));var e=N(document.createEvent(b)),f=hb[b],g=[c];return Object.keys(f).forEach(function(a){var b=null!=d&&a in d?d[a]:f[a];"relatedTarget"===a&&(b=N(b)),g.push(b)}),e["init"+b].apply(e,g),e}function y(){t.call(this)}function z(a){return"function"==typeof a?!0:a&&a.handleEvent}function A(a){switch(a){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function B(a){this.impl=a}function C(a){return a instanceof P.ShadowRoot&&(a=a.host),N(a)}function D(a,b){var c=Q.get(a);if(c)for(var d=0;d<c.length;d++)if(!c[d].removed&&c[d].type===b)return!0;return!1}function E(a,b){for(var c=N(a);c;c=c.parentNode)if(D(O(c),b))return!0;return!1}function F(a){J(a,lb)}function G(b,c,d,e){a.renderAllPending();for(var f=O(mb.call(c.impl,d,e)),h=g(f,this),i=0;i<h.length;i++){var j=h[i];if(j.currentTarget===b)return j.target}return null}function H(a){return function(){var b=Z.get(this);return b&&b[a]&&b[a].value||null}}function I(a){var b=a.slice(2);return function(c){var d=Z.get(this);d||(d=Object.create(null),Z.set(this,d));var e=d[a];if(e&&this.removeEventListener(b,e.wrapped,!1),"function"==typeof c){var f=function(b){var d=c.call(this,b);d===!1?b.preventDefault():"onbeforeunload"===a&&"string"==typeof d&&(b.returnValue=d)};this.addEventListener(b,f,!1),d[a]={value:c,wrapped:f}}}}var J=a.forwardMethodsToWrapper,K=a.getTreeScope,L=a.mixin,M=a.registerWrapper,N=a.unwrap,O=a.wrap,P=a.wrappers,Q=(new WeakMap,new WeakMap),R=new WeakMap,S=new WeakMap,T=new WeakMap,U=new WeakMap,V=new WeakMap,W=new WeakMap,X=new WeakMap,Y=new WeakMap,Z=new WeakMap,$=new WeakMap;s.prototype={equals:function(a){return this.handler===a.handler&&this.type===a.type&&this.capture===a.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var _=window.Event;_.prototype.polymerBlackList_={returnValue:!0,keyLocation:!0},t.prototype={get target(){return T.get(this)},get currentTarget(){return U.get(this)},get eventPhase(){return W.get(this)},get path(){var a=new P.NodeList,b=$.get(this);if(b){for(var c=0,d=b.length-1,e=K(U.get(this)),f=0;d>=f;f++){var g=b[f].currentTarget,h=K(g);h.contains(e)&&(f!==d||g instanceof P.Node)&&(a[c++]=g)}a.length=c}return a},stopPropagation:function(){X.set(this,!0)},stopImmediatePropagation:function(){X.set(this,!0),Y.set(this,!0)}},M(_,t,document.createEvent("Event"));
-var ab=v("UIEvent",t),bb=v("CustomEvent",t),cb={get relatedTarget(){return V.get(this)||O(N(this).relatedTarget)}},db=L({initMouseEvent:w("initMouseEvent",14)},cb),eb=L({initFocusEvent:w("initFocusEvent",5)},cb),fb=v("MouseEvent",ab,db),gb=v("FocusEvent",ab,eb),hb=Object.create(null),ib=function(){try{new window.FocusEvent("focus")}catch(a){return!1}return!0}();if(!ib){var jb=function(a,b,c){if(c){var d=hb[c];b=L(L({},d),b)}hb[a]=b};jb("Event",{bubbles:!1,cancelable:!1}),jb("CustomEvent",{detail:null},"Event"),jb("UIEvent",{view:null,detail:0},"Event"),jb("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),jb("FocusEvent",{relatedTarget:null},"UIEvent")}y.prototype=Object.create(t.prototype),L(y.prototype,{get returnValue(){return this.impl.returnValue},set returnValue(a){this.impl.returnValue=a}});var kb=window.EventTarget,lb=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(a){var b=a.prototype;lb.forEach(function(a){Object.defineProperty(b,a+"_",{value:b[a]})})}),B.prototype={addEventListener:function(a,b,c){if(z(b)&&!A(a)){var d=new s(a,b,c),e=Q.get(this);if(e){for(var f=0;f<e.length;f++)if(d.equals(e[f]))return}else e=[],Q.set(this,e);e.push(d);var g=C(this);g.addEventListener_(a,m,!0)}},removeEventListener:function(a,b,c){c=Boolean(c);var d=Q.get(this);if(d){for(var e=0,f=!1,g=0;g<d.length;g++)d[g].type===a&&d[g].capture===c&&(e++,d[g].handler===b&&(f=!0,d[g].remove()));if(f&&1===e){var h=C(this);h.removeEventListener_(a,m,!0)}}},dispatchEvent:function(b){var c=N(b),d=c.type;R.set(c,!1),a.renderAllPending();var e;E(this,d)||(e=function(){},this.addEventListener(d,e,!0));try{return N(this).dispatchEvent_(c)}finally{e&&this.removeEventListener(d,e,!0)}}},kb&&M(kb,B);var mb=document.elementFromPoint;a.adjustRelatedTarget=i,a.elementFromPoint=G,a.getEventHandlerGetter=H,a.getEventHandlerSetter=I,a.wrapEventTargetMethods=F,a.wrappers.BeforeUnloadEvent=y,a.wrappers.CustomEvent=bb,a.wrappers.Event=t,a.wrappers.EventTarget=B,a.wrappers.FocusEvent=gb,a.wrappers.MouseEvent=fb,a.wrappers.UIEvent=ab}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){Object.defineProperty(a,b,{enumerable:!1})}function c(){this.length=0,b(this,"length")}function d(a){if(null==a)return a;for(var b=new c,d=0,e=a.length;e>d;d++)b[d]=f(a[d]);return b.length=e,b}function e(a,b){a.prototype[b]=function(){return d(this.impl[b].apply(this.impl,arguments))}}var f=a.wrap;c.prototype={item:function(a){return this[a]}},b(c.prototype,"item"),a.wrappers.NodeList=c,a.addWrapNodeListMethod=e,a.wrapNodeList=d}(window.ShadowDOMPolyfill),function(a){"use strict";a.wrapHTMLCollection=a.wrapNodeList,a.wrappers.HTMLCollection=a.wrappers.NodeList}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){A(a instanceof w)}function c(a){var b=new y;return b[0]=a,b.length=1,b}function d(a,b,c){C(b,"childList",{removedNodes:c,previousSibling:a.previousSibling,nextSibling:a.nextSibling})}function e(a,b){C(a,"childList",{removedNodes:b})}function f(a,b,d,e){if(a instanceof DocumentFragment){var f=h(a);N=!0;for(var g=f.length-1;g>=0;g--)a.removeChild(f[g]),f[g].parentNode_=b;N=!1;for(var g=0;g<f.length;g++)f[g].previousSibling_=f[g-1]||d,f[g].nextSibling_=f[g+1]||e;return d&&(d.nextSibling_=f[0]),e&&(e.previousSibling_=f[f.length-1]),f}var f=c(a),i=a.parentNode;return i&&i.removeChild(a),a.parentNode_=b,a.previousSibling_=d,a.nextSibling_=e,d&&(d.nextSibling_=a),e&&(e.previousSibling_=a),f}function g(a){if(a instanceof DocumentFragment)return h(a);var b=c(a),e=a.parentNode;return e&&d(a,e,b),b}function h(a){for(var b=new y,c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b.length=c,e(a,b),b}function i(a){return a}function j(a,b){I(a,b),a.nodeIsInserted_()}function k(a,b){for(var c=D(b),d=0;d<a.length;d++)j(a[d],c)}function l(a){I(a,new z(a,null))}function m(a){for(var b=0;b<a.length;b++)l(a[b])}function n(a,b){var c=a.nodeType===w.DOCUMENT_NODE?a:a.ownerDocument;c!==b.ownerDocument&&c.adoptNode(b)}function o(b,c){if(c.length){var d=b.ownerDocument;if(d!==c[0].ownerDocument)for(var e=0;e<c.length;e++)a.adoptNodeNoRemove(c[e],d)}}function p(a,b){o(a,b);var c=b.length;if(1===c)return J(b[0]);for(var d=J(a.ownerDocument.createDocumentFragment()),e=0;c>e;e++)d.appendChild(J(b[e]));return d}function q(a){if(void 0!==a.firstChild_)for(var b=a.firstChild_;b;){var c=b;b=b.nextSibling_,c.parentNode_=c.previousSibling_=c.nextSibling_=void 0}a.firstChild_=a.lastChild_=void 0}function r(a){if(a.invalidateShadowRenderer()){for(var b=a.firstChild;b;){A(b.parentNode===a);var c=b.nextSibling,d=J(b),e=d.parentNode;e&&U.call(e,d),b.previousSibling_=b.nextSibling_=b.parentNode_=null,b=c}a.firstChild_=a.lastChild_=null}else for(var c,f=J(a),g=f.firstChild;g;)c=g.nextSibling,U.call(f,g),g=c}function s(a){var b=a.parentNode;return b&&b.invalidateShadowRenderer()}function t(a){for(var b,c=0;c<a.length;c++)b=a[c],b.parentNode.removeChild(b)}function u(a,b,c){var d;if(d=K(c?O.call(c,a.impl,!1):P.call(a.impl,!1)),b){for(var e=a.firstChild;e;e=e.nextSibling)d.appendChild(u(e,!0,c));if(a instanceof M.HTMLTemplateElement)for(var f=d.content,e=a.content.firstChild;e;e=e.nextSibling)f.appendChild(u(e,!0,c))}return d}function v(a,b){if(!b||D(a)!==D(b))return!1;for(var c=b;c;c=c.parentNode)if(c===a)return!0;return!1}function w(a){A(a instanceof Q),x.call(this,a),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0,this.treeScope_=void 0}var x=a.wrappers.EventTarget,y=a.wrappers.NodeList,z=a.TreeScope,A=a.assert,B=a.defineWrapGetter,C=a.enqueueMutation,D=a.getTreeScope,E=a.isWrapper,F=a.mixin,G=a.registerTransientObservers,H=a.registerWrapper,I=a.setTreeScope,J=a.unwrap,K=a.wrap,L=a.wrapIfNeeded,M=a.wrappers,N=!1,O=document.importNode,P=window.Node.prototype.cloneNode,Q=window.Node,R=window.DocumentFragment,S=(Q.prototype.appendChild,Q.prototype.compareDocumentPosition),T=Q.prototype.insertBefore,U=Q.prototype.removeChild,V=Q.prototype.replaceChild,W=/Trident/.test(navigator.userAgent),X=W?function(a,b){try{U.call(a,b)}catch(c){if(!(a instanceof R))throw c}}:function(a,b){U.call(a,b)};w.prototype=Object.create(x.prototype),F(w.prototype,{appendChild:function(a){return this.insertBefore(a,null)},insertBefore:function(a,c){b(a);var d;c?E(c)?d=J(c):(d=c,c=K(d)):(c=null,d=null),c&&A(c.parentNode===this);var e,h=c?c.previousSibling:this.lastChild,i=!this.invalidateShadowRenderer()&&!s(a);if(e=i?g(a):f(a,this,h,c),i)n(this,a),q(this),T.call(this.impl,J(a),d);else{h||(this.firstChild_=e[0]),c||(this.lastChild_=e[e.length-1]);var j=d?d.parentNode:this.impl;j?T.call(j,p(this,e),d):o(this,e)}return C(this,"childList",{addedNodes:e,nextSibling:c,previousSibling:h}),k(e,this),a},removeChild:function(a){if(b(a),a.parentNode!==this){for(var d=!1,e=(this.childNodes,this.firstChild);e;e=e.nextSibling)if(e===a){d=!0;break}if(!d)throw new Error("NotFoundError")}var f=J(a),g=a.nextSibling,h=a.previousSibling;if(this.invalidateShadowRenderer()){var i=this.firstChild,j=this.lastChild,k=f.parentNode;k&&X(k,f),i===a&&(this.firstChild_=g),j===a&&(this.lastChild_=h),h&&(h.nextSibling_=g),g&&(g.previousSibling_=h),a.previousSibling_=a.nextSibling_=a.parentNode_=void 0}else q(this),X(this.impl,f);return N||C(this,"childList",{removedNodes:c(a),nextSibling:g,previousSibling:h}),G(this,a),a},replaceChild:function(a,d){b(a);var e;if(E(d)?e=J(d):(e=d,d=K(e)),d.parentNode!==this)throw new Error("NotFoundError");var h,i=d.nextSibling,j=d.previousSibling,m=!this.invalidateShadowRenderer()&&!s(a);return m?h=g(a):(i===a&&(i=a.nextSibling),h=f(a,this,j,i)),m?(n(this,a),q(this),V.call(this.impl,J(a),e)):(this.firstChild===d&&(this.firstChild_=h[0]),this.lastChild===d&&(this.lastChild_=h[h.length-1]),d.previousSibling_=d.nextSibling_=d.parentNode_=void 0,e.parentNode&&V.call(e.parentNode,p(this,h),e)),C(this,"childList",{addedNodes:h,removedNodes:c(d),nextSibling:i,previousSibling:j}),l(d),k(h,this),d},nodeIsInserted_:function(){for(var a=this.firstChild;a;a=a.nextSibling)a.nodeIsInserted_()},hasChildNodes:function(){return null!==this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:K(this.impl.parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:K(this.impl.firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:K(this.impl.lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:K(this.impl.nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:K(this.impl.previousSibling)},get parentElement(){for(var a=this.parentNode;a&&a.nodeType!==w.ELEMENT_NODE;)a=a.parentNode;return a},get textContent(){for(var a="",b=this.firstChild;b;b=b.nextSibling)b.nodeType!=w.COMMENT_NODE&&(a+=b.textContent);return a},set textContent(a){var b=i(this.childNodes);if(this.invalidateShadowRenderer()){if(r(this),""!==a){var c=this.impl.ownerDocument.createTextNode(a);this.appendChild(c)}}else q(this),this.impl.textContent=a;var d=i(this.childNodes);C(this,"childList",{addedNodes:d,removedNodes:b}),m(b),k(d,this)},get childNodes(){for(var a=new y,b=0,c=this.firstChild;c;c=c.nextSibling)a[b++]=c;return a.length=b,a},cloneNode:function(a){return u(this,a)},contains:function(a){return v(this,L(a))},compareDocumentPosition:function(a){return S.call(this.impl,J(a))},normalize:function(){for(var a,b,c=i(this.childNodes),d=[],e="",f=0;f<c.length;f++)b=c[f],b.nodeType===w.TEXT_NODE?a||b.data.length?a?(e+=b.data,d.push(b)):a=b:this.removeNode(b):(a&&d.length&&(a.data+=e,cleanUpNodes(d)),d=[],e="",a=null,b.childNodes.length&&b.normalize());a&&d.length&&(a.data+=e,t(d))}}),B(w,"ownerDocument"),H(Q,w,document.createDocumentFragment()),delete w.prototype.querySelector,delete w.prototype.querySelectorAll,w.prototype=F(Object.create(x.prototype),w.prototype),a.cloneNode=u,a.nodeWasAdded=j,a.nodeWasRemoved=l,a.nodesWereAdded=k,a.nodesWereRemoved=m,a.snapshotNodeList=i,a.wrappers.Node=w}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,c){for(var d,e=a.firstElementChild;e;){if(e.matches(c))return e;if(d=b(e,c))return d;e=e.nextElementSibling}return null}function c(a,b,d){for(var e=a.firstElementChild;e;)e.matches(b)&&(d[d.length++]=e),c(e,b,d),e=e.nextElementSibling;return d}var d={querySelector:function(a){return b(this,a)},querySelectorAll:function(a){return c(this,a,new NodeList)}},e={getElementsByTagName:function(a){return this.querySelectorAll(a)},getElementsByClassName:function(a){return this.querySelectorAll("."+a)},getElementsByTagNameNS:function(a,b){if("*"===a)return this.getElementsByTagName(b);for(var c=new NodeList,d=this.getElementsByTagName(b),e=0,f=0;e<d.length;e++)d[e].namespaceURI===a&&(c[f++]=d[e]);return c.length=f,c}};a.GetElementsByInterface=e,a.SelectorsInterface=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}function c(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}var d=a.wrappers.NodeList,e={get firstElementChild(){return b(this.firstChild)},get lastElementChild(){return c(this.lastChild)},get childElementCount(){for(var a=0,b=this.firstElementChild;b;b=b.nextElementSibling)a++;return a},get children(){for(var a=new d,b=0,c=this.firstElementChild;c;c=c.nextElementSibling)a[b++]=c;return a.length=b,a}},f={get nextElementSibling(){return b(this.nextSibling)},get previousElementSibling(){return c(this.previousSibling)}};a.ChildNodeInterface=f,a.ParentNodeInterface=e}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}var c=a.ChildNodeInterface,d=a.wrappers.Node,e=a.enqueueMutation,f=a.mixin,g=a.registerWrapper,h=window.CharacterData;b.prototype=Object.create(d.prototype),f(b.prototype,{get textContent(){return this.data},set textContent(a){this.data=a},get data(){return this.impl.data},set data(a){var b=this.impl.data;e(this,"characterData",{oldValue:b}),this.impl.data=a}}),f(b.prototype,c),g(h,b,document.createTextNode("")),a.wrappers.CharacterData=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a>>>0}function c(a){d.call(this,a)}var d=a.wrappers.CharacterData,e=(a.enqueueMutation,a.mixin),f=a.registerWrapper,g=window.Text;c.prototype=Object.create(d.prototype),e(c.prototype,{splitText:function(a){a=b(a);var c=this.data;if(a>c.length)throw new Error("IndexSizeError");var d=c.slice(0,a),e=c.slice(a);this.data=d;var f=this.ownerDocument.createTextNode(e);return this.parentNode&&this.parentNode.insertBefore(f,this.nextSibling),f}}),f(g,c,document.createTextNode("")),a.wrappers.Text=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b,c){var d=b.parentNode;if(d&&d.shadowRoot){var e=a.getRendererForHost(d);e.dependsOnAttribute(c)&&e.invalidate()}}function c(a,b,c){k(a,"attributes",{name:b,namespace:null,oldValue:c})}function d(a){h.call(this,a)}function e(a,c,d){var e=d||c;Object.defineProperty(a,c,{get:function(){return this.impl[c]},set:function(a){this.impl[c]=a,b(this,e)},configurable:!0,enumerable:!0})}var f=a.ChildNodeInterface,g=a.GetElementsByInterface,h=a.wrappers.Node,i=a.ParentNodeInterface,j=a.SelectorsInterface,k=(a.addWrapNodeListMethod,a.enqueueMutation),l=a.mixin,m=(a.oneOf,a.registerWrapper),n=a.wrappers,o=window.Element,p=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(a){return o.prototype[a]}),q=p[0],r=o.prototype[q];d.prototype=Object.create(h.prototype),l(d.prototype,{createShadowRoot:function(){var b=new n.ShadowRoot(this);this.impl.polymerShadowRoot_=b;var c=a.getRendererForHost(this);return c.invalidate(),b},get shadowRoot(){return this.impl.polymerShadowRoot_||null},setAttribute:function(a,d){var e=this.impl.getAttribute(a);this.impl.setAttribute(a,d),c(this,a,e),b(this,a)},removeAttribute:function(a){var d=this.impl.getAttribute(a);this.impl.removeAttribute(a),c(this,a,d),b(this,a)},matches:function(a){return r.call(this.impl,a)}}),p.forEach(function(a){"matches"!==a&&(d.prototype[a]=function(a){return this.matches(a)})}),o.prototype.webkitCreateShadowRoot&&(d.prototype.webkitCreateShadowRoot=d.prototype.createShadowRoot),e(d.prototype,"id"),e(d.prototype,"className","class"),l(d.prototype,f),l(d.prototype,g),l(d.prototype,i),l(d.prototype,j),m(o,d,document.createElementNS(null,"x")),a.matchesNames=p,a.wrappers.Element=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a){case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;";case'"':return"&quot;";case" ":return"&nbsp;"}}function c(a){return a.replace(z,b)}function d(a){return a.replace(A,b)}function e(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}function f(a,b){switch(a.nodeType){case Node.ELEMENT_NODE:for(var e,f=a.tagName.toLowerCase(),h="<"+f,i=a.attributes,j=0;e=i[j];j++)h+=" "+e.name+'="'+c(e.value)+'"';return h+=">",B[f]?h:h+g(a)+"</"+f+">";case Node.TEXT_NODE:var k=a.data;return b&&C[b.localName]?k:d(k);case Node.COMMENT_NODE:return"<!--"+a.data+"-->";default:throw console.error(a),new Error("not implemented")}}function g(a){a instanceof y.HTMLTemplateElement&&(a=a.content);for(var b="",c=a.firstChild;c;c=c.nextSibling)b+=f(c,a);return b}function h(a,b,c){var d=c||"div";a.textContent="";var e=w(a.ownerDocument.createElement(d));e.innerHTML=b;for(var f;f=e.firstChild;)a.appendChild(x(f))}function i(a){o.call(this,a)}function j(a,b){var c=w(a.cloneNode(!1));c.innerHTML=b;for(var d,e=w(document.createDocumentFragment());d=c.firstChild;)e.appendChild(d);return x(e)}function k(b){return function(){return a.renderAllPending(),this.impl[b]}}function l(a){p(i,a,k(a))}function m(b){Object.defineProperty(i.prototype,b,{get:k(b),set:function(c){a.renderAllPending(),this.impl[b]=c},configurable:!0,enumerable:!0})}function n(b){Object.defineProperty(i.prototype,b,{value:function(){return a.renderAllPending(),this.impl[b].apply(this.impl,arguments)},configurable:!0,enumerable:!0})}var o=a.wrappers.Element,p=a.defineGetter,q=a.enqueueMutation,r=a.mixin,s=a.nodesWereAdded,t=a.nodesWereRemoved,u=a.registerWrapper,v=a.snapshotNodeList,w=a.unwrap,x=a.wrap,y=a.wrappers,z=/[&\u00A0"]/g,A=/[&\u00A0<>]/g,B=e(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),C=e(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),D=/MSIE/.test(navigator.userAgent),E=window.HTMLElement,F=window.HTMLTemplateElement;i.prototype=Object.create(o.prototype),r(i.prototype,{get innerHTML(){return g(this)},set innerHTML(a){if(D&&C[this.localName])return void(this.textContent=a);var b=v(this.childNodes);this.invalidateShadowRenderer()?this instanceof y.HTMLTemplateElement?h(this.content,a):h(this,a,this.tagName):!F&&this instanceof y.HTMLTemplateElement?h(this.content,a):this.impl.innerHTML=a;var c=v(this.childNodes);q(this,"childList",{addedNodes:c,removedNodes:b}),t(b),s(c,this)},get outerHTML(){return f(this,this.parentNode)},set outerHTML(a){var b=this.parentNode;if(b){b.invalidateShadowRenderer();var c=j(b,a);b.replaceChild(c,this)}},insertAdjacentHTML:function(a,b){var c,d;switch(String(a).toLowerCase()){case"beforebegin":c=this.parentNode,d=this;break;case"afterend":c=this.parentNode,d=this.nextSibling;break;case"afterbegin":c=this,d=this.firstChild;break;case"beforeend":c=this,d=null;break;default:return}var e=j(c,b);c.insertBefore(e,d)}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(l),["scrollLeft","scrollTop"].forEach(m),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(n),u(E,i,document.createElement("b")),a.wrappers.HTMLElement=i,a.getInnerHTML=g,a.setInnerHTML=h}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrap,g=window.HTMLCanvasElement;b.prototype=Object.create(c.prototype),d(b.prototype,{getContext:function(){var a=this.impl.getContext.apply(this.impl,arguments);return a&&f(a)}}),e(g,b,document.createElement("canvas")),a.wrappers.HTMLCanvasElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLContentElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get select(){return this.getAttribute("select")},set select(a){this.setAttribute("select",a)},setAttribute:function(a,b){c.prototype.setAttribute.call(this,a,b),"select"===String(a).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),f&&e(f,b),a.wrappers.HTMLContentElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a,b){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var e=f(document.createElement("img"));d.call(this,e),g(e,this),void 0!==a&&(e.width=a),void 0!==b&&(e.height=b)}var d=a.wrappers.HTMLElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLImageElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("img")),c.prototype=b.prototype,a.wrappers.HTMLImageElement=b,a.wrappers.Image=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLShadowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{}),f&&e(f,b),a.wrappers.HTMLShadowElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){if(!a.defaultView)return a;var b=k.get(a);if(!b){for(b=a.implementation.createHTMLDocument("");b.lastChild;)b.removeChild(b.lastChild);k.set(a,b)}return b}function c(a){for(var c,d=b(a.ownerDocument),e=h(d.createDocumentFragment());c=a.firstChild;)e.appendChild(c);return e}function d(a){if(e.call(this,a),!l){var b=c(a);j.set(this,i(b))}}var e=a.wrappers.HTMLElement,f=a.mixin,g=a.registerWrapper,h=a.unwrap,i=a.wrap,j=new WeakMap,k=new WeakMap,l=window.HTMLTemplateElement;d.prototype=Object.create(e.prototype),f(d.prototype,{get content(){return l?i(this.impl.content):j.get(this)}}),l&&g(l,d),a.wrappers.HTMLTemplateElement=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.registerWrapper,e=window.HTMLMediaElement;b.prototype=Object.create(c.prototype),d(e,b,document.createElement("audio")),a.wrappers.HTMLMediaElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var b=f(document.createElement("audio"));d.call(this,b),g(b,this),b.setAttribute("preload","auto"),void 0!==a&&b.setAttribute("src",a)}var d=a.wrappers.HTMLMediaElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLAudioElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("audio")),c.prototype=b.prototype,a.wrappers.HTMLAudioElement=b,a.wrappers.Audio=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a.replace(/\s+/g," ").trim()}function c(a){e.call(this,a)}function d(a,b,c,f){if(!(this instanceof d))throw new TypeError("DOM object constructor cannot be called as a function.");var g=i(document.createElement("option"));e.call(this,g),h(g,this),void 0!==a&&(g.text=a),void 0!==b&&g.setAttribute("value",b),c===!0&&g.setAttribute("selected",""),g.selected=f===!0}var e=a.wrappers.HTMLElement,f=a.mixin,g=a.registerWrapper,h=a.rewrap,i=a.unwrap,j=a.wrap,k=window.HTMLOptionElement;c.prototype=Object.create(e.prototype),f(c.prototype,{get text(){return b(this.textContent)},set text(a){this.textContent=b(String(a))},get form(){return j(i(this).form)}}),g(k,c,document.createElement("option")),d.prototype=c.prototype,a.wrappers.HTMLOptionElement=c,a.wrappers.Option=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.wrap,h=window.HTMLSelectElement;b.prototype=Object.create(c.prototype),d(b.prototype,{add:function(a,b){"object"==typeof b&&(b=f(b)),f(this).add(f(a),b)},remove:function(a){"object"==typeof a&&(a=f(a)),f(this).remove(a)},get form(){return g(f(this).form)}}),e(h,b,document.createElement("select")),a.wrappers.HTMLSelectElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.wrap,h=a.wrapHTMLCollection,i=window.HTMLTableElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get caption(){return g(f(this).caption)},createCaption:function(){return g(f(this).createCaption())},get tHead(){return g(f(this).tHead)},createTHead:function(){return g(f(this).createTHead())},createTFoot:function(){return g(f(this).createTFoot())},get tFoot(){return g(f(this).tFoot)},get tBodies(){return h(f(this).tBodies)},createTBody:function(){return g(f(this).createTBody())},get rows(){return h(f(this).rows)},insertRow:function(a){return g(f(this).insertRow(a))}}),e(i,b,document.createElement("table")),a.wrappers.HTMLTableElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrapHTMLCollection,g=a.unwrap,h=a.wrap,i=window.HTMLTableSectionElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get rows(){return f(g(this).rows)},insertRow:function(a){return h(g(this).insertRow(a))}}),e(i,b,document.createElement("thead")),a.wrappers.HTMLTableSectionElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrapHTMLCollection,g=a.unwrap,h=a.wrap,i=window.HTMLTableRowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get cells(){return f(g(this).cells)},insertCell:function(a){return h(g(this).insertCell(a))}}),e(i,b,document.createElement("tr")),a.wrappers.HTMLTableRowElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a.localName){case"content":return new c(a);case"shadow":return new e(a);case"template":return new f(a)}d.call(this,a)}var c=a.wrappers.HTMLContentElement,d=a.wrappers.HTMLElement,e=a.wrappers.HTMLShadowElement,f=a.wrappers.HTMLTemplateElement,g=(a.mixin,a.registerWrapper),h=window.HTMLUnknownElement;b.prototype=Object.create(d.prototype),g(h,b),a.wrappers.HTMLUnknownElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.registerObject,c="http://www.w3.org/2000/svg",d=document.createElementNS(c,"title"),e=b(d),f=Object.getPrototypeOf(e.prototype).constructor;a.wrappers.SVGElement=f}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){m.call(this,a)}var c=a.mixin,d=a.registerWrapper,e=a.unwrap,f=a.wrap,g=window.SVGUseElement,h="http://www.w3.org/2000/svg",i=f(document.createElementNS(h,"g")),j=document.createElementNS(h,"use"),k=i.constructor,l=Object.getPrototypeOf(k.prototype),m=l.constructor;b.prototype=Object.create(l),"instanceRoot"in j&&c(b.prototype,{get instanceRoot(){return f(e(this).instanceRoot)},get animatedInstanceRoot(){return f(e(this).animatedInstanceRoot)}}),d(g,b,j),a.wrappers.SVGUseElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.mixin,e=a.registerWrapper,f=a.wrap,g=window.SVGElementInstance;g&&(b.prototype=Object.create(c.prototype),d(b.prototype,{get correspondingElement(){return f(this.impl.correspondingElement)},get correspondingUseElement(){return f(this.impl.correspondingUseElement)},get parentNode(){return f(this.impl.parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return f(this.impl.firstChild)},get lastChild(){return f(this.impl.lastChild)},get previousSibling(){return f(this.impl.previousSibling)},get nextSibling(){return f(this.impl.nextSibling)}}),e(g,b),a.wrappers.SVGElementInstance=b)}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrap,f=a.unwrapIfNeeded,g=a.wrap,h=window.CanvasRenderingContext2D;c(b.prototype,{get canvas(){return g(this.impl.canvas)},drawImage:function(){arguments[0]=f(arguments[0]),this.impl.drawImage.apply(this.impl,arguments)},createPattern:function(){return arguments[0]=e(arguments[0]),this.impl.createPattern.apply(this.impl,arguments)}}),d(h,b,document.createElement("canvas").getContext("2d")),a.wrappers.CanvasRenderingContext2D=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrapIfNeeded,f=a.wrap,g=window.WebGLRenderingContext;if(g){c(b.prototype,{get canvas(){return f(this.impl.canvas)},texImage2D:function(){arguments[5]=e(arguments[5]),this.impl.texImage2D.apply(this.impl,arguments)},texSubImage2D:function(){arguments[6]=e(arguments[6]),this.impl.texSubImage2D.apply(this.impl,arguments)}});var h=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};d(g,b,h),a.wrappers.WebGLRenderingContext=b}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap,g=window.Range;b.prototype={get startContainer(){return f(this.impl.startContainer)},get endContainer(){return f(this.impl.endContainer)},get commonAncestorContainer(){return f(this.impl.commonAncestorContainer)},setStart:function(a,b){this.impl.setStart(e(a),b)},setEnd:function(a,b){this.impl.setEnd(e(a),b)},setStartBefore:function(a){this.impl.setStartBefore(e(a))},setStartAfter:function(a){this.impl.setStartAfter(e(a))},setEndBefore:function(a){this.impl.setEndBefore(e(a))},setEndAfter:function(a){this.impl.setEndAfter(e(a))},selectNode:function(a){this.impl.selectNode(e(a))},selectNodeContents:function(a){this.impl.selectNodeContents(e(a))},compareBoundaryPoints:function(a,b){return this.impl.compareBoundaryPoints(a,d(b))},extractContents:function(){return f(this.impl.extractContents())},cloneContents:function(){return f(this.impl.cloneContents())},insertNode:function(a){this.impl.insertNode(e(a))},surroundContents:function(a){this.impl.surroundContents(e(a))},cloneRange:function(){return f(this.impl.cloneRange())},isPointInRange:function(a,b){return this.impl.isPointInRange(e(a),b)},comparePoint:function(a,b){return this.impl.comparePoint(e(a),b)},intersectsNode:function(a){return this.impl.intersectsNode(e(a))},toString:function(){return this.impl.toString()}},g.prototype.createContextualFragment&&(b.prototype.createContextualFragment=function(a){return f(this.impl.createContextualFragment(a))}),c(window.Range,b,document.createRange()),a.wrappers.Range=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.GetElementsByInterface,c=a.ParentNodeInterface,d=a.SelectorsInterface,e=a.mixin,f=a.registerObject,g=f(document.createDocumentFragment());e(g.prototype,c),e(g.prototype,d),e(g.prototype,b);var h=f(document.createComment(""));a.wrappers.Comment=h,a.wrappers.DocumentFragment=g}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=k(a.impl.ownerDocument.createDocumentFragment());c.call(this,b),i(b,this),this.treeScope_=new d(this,g(a));var e=a.shadowRoot;m.set(this,e),l.set(this,a)}var c=a.wrappers.DocumentFragment,d=a.TreeScope,e=a.elementFromPoint,f=a.getInnerHTML,g=a.getTreeScope,h=a.mixin,i=a.rewrap,j=a.setInnerHTML,k=a.unwrap,l=new WeakMap,m=new WeakMap,n=/[ \t\n\r\f]/;b.prototype=Object.create(c.prototype),h(b.prototype,{get innerHTML(){return f(this)},set innerHTML(a){j(this,a),this.invalidateShadowRenderer()},get olderShadowRoot(){return m.get(this)||null},get host(){return l.get(this)||null},invalidateShadowRenderer:function(){return l.get(this).invalidateShadowRenderer()},elementFromPoint:function(a,b){return e(this,this.ownerDocument,a,b)},getElementById:function(a){return n.test(a)?null:this.querySelector('[id="'+a+'"]')}}),a.wrappers.ShadowRoot=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){a.previousSibling_=a.previousSibling,a.nextSibling_=a.nextSibling,a.parentNode_=a.parentNode}function c(a,c,e){var f=G(a),g=G(c),h=e?G(e):null;if(d(c),b(c),e)a.firstChild===e&&(a.firstChild_=e),e.previousSibling_=e.previousSibling;else{a.lastChild_=a.lastChild,a.lastChild===a.firstChild&&(a.firstChild_=a.firstChild);var i=H(f.lastChild);i&&(i.nextSibling_=i.nextSibling)}f.insertBefore(g,h)}function d(a){var c=G(a),d=c.parentNode;if(d){var e=H(d);b(a),a.previousSibling&&(a.previousSibling.nextSibling_=a),a.nextSibling&&(a.nextSibling.previousSibling_=a),e.lastChild===a&&(e.lastChild_=a),e.firstChild===a&&(e.firstChild_=a),d.removeChild(c)}}function e(a,b){g(b).push(a),x(a,b);var c=J.get(a);c||J.set(a,c=[]),c.push(b)}function f(a){I.set(a,[])}function g(a){var b=I.get(a);return b||I.set(a,b=[]),b}function h(a){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}function i(a,b,c){for(var d=a.firstChild;d;d=d.nextSibling)if(b(d)){if(c(d)===!1)return}else i(d,b,c)}function j(a,b){var c=b.getAttribute("select");if(!c)return!0;if(c=c.trim(),!c)return!0;if(!(a instanceof z))return!1;if("*"===c||c===a.localName)return!0;if(!M.test(c))return!1;if(":"===c[0]&&!N.test(c))return!1;try{return a.matches(c)}catch(d){return!1}}function k(){for(var a=0;a<P.length;a++){var b=P[a],c=b.parentRenderer;c&&c.dirty||b.render()}P=[]}function l(){y=null,k()}function m(a){var b=L.get(a);return b||(b=new q(a),L.set(a,b)),b}function n(a){var b=E(a).root;return b instanceof D?b:null}function o(a){return m(a.host)}function p(a){this.skip=!1,this.node=a,this.childNodes=[]}function q(a){this.host=a,this.dirty=!1,this.invalidateAttributes(),this.associateNode(a)}function r(a){return a instanceof A}function s(a){return a instanceof A}function t(a){return a instanceof B}function u(a){return a instanceof B}function v(a){return a.shadowRoot
-}function w(a){for(var b=[],c=a.shadowRoot;c;c=c.olderShadowRoot)b.push(c);return b}function x(a,b){K.set(a,b)}var y,z=a.wrappers.Element,A=a.wrappers.HTMLContentElement,B=a.wrappers.HTMLShadowElement,C=a.wrappers.Node,D=a.wrappers.ShadowRoot,E=(a.assert,a.getTreeScope),F=(a.mixin,a.oneOf),G=a.unwrap,H=a.wrap,I=new WeakMap,J=new WeakMap,K=new WeakMap,L=new WeakMap,M=/^[*.:#[a-zA-Z_|]/,N=new RegExp("^:("+["link","visited","target","enabled","disabled","checked","indeterminate","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-of-type"].join("|")+")"),O=F(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),P=[],Q=new ArraySplice;Q.equals=function(a,b){return G(a.node)===b},p.prototype={append:function(a){var b=new p(a);return this.childNodes.push(b),b},sync:function(a){if(!this.skip){for(var b=this.node,e=this.childNodes,f=h(G(b)),g=a||new WeakMap,i=Q.calculateSplices(e,f),j=0,k=0,l=0,m=0;m<i.length;m++){for(var n=i[m];l<n.index;l++)k++,e[j++].sync(g);for(var o=n.removed.length,p=0;o>p;p++){var q=H(f[k++]);g.get(q)||d(q)}for(var r=n.addedCount,s=f[k]&&H(f[k]),p=0;r>p;p++){var t=e[j++],u=t.node;c(b,u,s),g.set(u,!0),t.sync(g)}l+=r}for(var m=l;m<e.length;m++)e[m].sync(g)}}},q.prototype={render:function(a){if(this.dirty){this.invalidateAttributes(),this.treeComposition();var b=this.host,c=b.shadowRoot;this.associateNode(b);for(var d=!e,e=a||new p(b),f=c.firstChild;f;f=f.nextSibling)this.renderNode(c,e,f,!1);d&&e.sync(),this.dirty=!1}},get parentRenderer(){return E(this.host).renderer},invalidate:function(){if(!this.dirty){if(this.dirty=!0,P.push(this),y)return;y=window[O](l,0)}},renderNode:function(a,b,c,d){if(v(c)){b=b.append(c);var e=m(c);e.dirty=!0,e.render(b)}else r(c)?this.renderInsertionPoint(a,b,c,d):t(c)?this.renderShadowInsertionPoint(a,b,c):this.renderAsAnyDomTree(a,b,c,d)},renderAsAnyDomTree:function(a,b,c,d){if(b=b.append(c),v(c)){var e=m(c);b.skip=!e.dirty,e.render(b)}else for(var f=c.firstChild;f;f=f.nextSibling)this.renderNode(a,b,f,d)},renderInsertionPoint:function(a,b,c,d){var e=g(c);if(e.length){this.associateNode(c);for(var f=0;f<e.length;f++){var h=e[f];r(h)&&d?this.renderInsertionPoint(a,b,h,d):this.renderAsAnyDomTree(a,b,h,d)}}else this.renderFallbackContent(a,b,c);this.associateNode(c.parentNode)},renderShadowInsertionPoint:function(a,b,c){var d=a.olderShadowRoot;if(d){x(d,c),this.associateNode(c.parentNode);for(var e=d.firstChild;e;e=e.nextSibling)this.renderNode(d,b,e,!0)}else this.renderFallbackContent(a,b,c)},renderFallbackContent:function(a,b,c){this.associateNode(c),this.associateNode(c.parentNode);for(var d=c.firstChild;d;d=d.nextSibling)this.renderAsAnyDomTree(a,b,d,!1)},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(a){if(a){var b=this.attributes;/\.\w+/.test(a)&&(b["class"]=!0),/#\w+/.test(a)&&(b.id=!0),a.replace(/\[\s*([^\s=\|~\]]+)/g,function(a,c){b[c]=!0})}},dependsOnAttribute:function(a){return this.attributes[a]},distribute:function(a,b){var c=this;i(a,s,function(a){f(a),c.updateDependentAttributes(a.getAttribute("select"));for(var d=0;d<b.length;d++){var g=b[d];void 0!==g&&j(g,a)&&(e(g,a),b[d]=void 0)}})},treeComposition:function(){for(var a=this.host,b=a.shadowRoot,c=[],d=a.firstChild;d;d=d.nextSibling)if(r(d)){var e=g(d);e&&e.length||(e=h(d)),c.push.apply(c,e)}else c.push(d);for(var f,j;b;){if(f=void 0,i(b,u,function(a){return f=a,!1}),j=f,this.distribute(b,c),j){var k=b.olderShadowRoot;if(k){b=k,x(b,j);continue}break}break}},associateNode:function(a){a.impl.polymerShadowRenderer_=this}},C.prototype.invalidateShadowRenderer=function(){var a=this.impl.polymerShadowRenderer_;return a?(a.invalidate(),!0):!1},A.prototype.getDistributedNodes=function(){return k(),g(this)},B.prototype.nodeIsInserted_=A.prototype.nodeIsInserted_=function(){this.invalidateShadowRenderer();var a,b=n(this);b&&(a=o(b)),this.impl.polymerShadowRenderer_=a,a&&a.invalidate()},a.eventParentsTable=J,a.getRendererForHost=m,a.getShadowTrees=w,a.insertionParentTable=K,a.renderAllPending=k,a.visual={insertBefore:c,remove:d}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b){if(window[b]){d(!a.wrappers[b]);var i=function(a){c.call(this,a)};i.prototype=Object.create(c.prototype),e(i.prototype,{get form(){return h(g(this).form)}}),f(window[b],i,document.createElement(b.slice(4,-7))),a.wrappers[b]=i}}var c=a.wrappers.HTMLElement,d=a.assert,e=a.mixin,f=a.registerWrapper,g=a.unwrap,h=a.wrap,i=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOutputElement","HTMLTextAreaElement"];i.forEach(b)}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}{var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap;window.Selection}b.prototype={get anchorNode(){return f(this.impl.anchorNode)},get focusNode(){return f(this.impl.focusNode)},addRange:function(a){this.impl.addRange(d(a))},collapse:function(a,b){this.impl.collapse(e(a),b)},containsNode:function(a,b){return this.impl.containsNode(e(a),b)},extend:function(a,b){this.impl.extend(e(a),b)},getRangeAt:function(a){return f(this.impl.getRangeAt(a))},removeRange:function(a){this.impl.removeRange(d(a))},selectAllChildren:function(a){this.impl.selectAllChildren(e(a))},toString:function(){return this.impl.toString()}},c(window.Selection,b,window.getSelection()),a.wrappers.Selection=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){k.call(this,a),this.treeScope_=new p(this,null)}function c(a){var c=document[a];b.prototype[a]=function(){return A(c.apply(this.impl,arguments))}}function d(a,b){D.call(b.impl,z(a)),e(a,b)}function e(a,b){a.shadowRoot&&b.adoptNode(a.shadowRoot),a instanceof o&&f(a,b);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}function f(a,b){var c=a.olderShadowRoot;c&&b.adoptNode(c)}function g(a){this.impl=a}function h(a,b){var c=document.implementation[b];a.prototype[b]=function(){return A(c.apply(this.impl,arguments))}}function i(a,b){var c=document.implementation[b];a.prototype[b]=function(){return c.apply(this.impl,arguments)}}var j=a.GetElementsByInterface,k=a.wrappers.Node,l=a.ParentNodeInterface,m=a.wrappers.Selection,n=a.SelectorsInterface,o=a.wrappers.ShadowRoot,p=a.TreeScope,q=a.cloneNode,r=a.defineWrapGetter,s=a.elementFromPoint,t=a.forwardMethodsToWrapper,u=a.matchesNames,v=a.mixin,w=a.registerWrapper,x=a.renderAllPending,y=a.rewrap,z=a.unwrap,A=a.wrap,B=a.wrapEventTargetMethods,C=(a.wrapNodeList,new WeakMap);b.prototype=Object.create(k.prototype),r(b,"documentElement"),r(b,"body"),r(b,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","getElementById"].forEach(c);var D=document.adoptNode,E=document.getSelection;if(v(b.prototype,{adoptNode:function(a){return a.parentNode&&a.parentNode.removeChild(a),d(a,this),a},elementFromPoint:function(a,b){return s(this,this,a,b)},importNode:function(a,b){return q(a,b,this.impl)},getSelection:function(){return x(),new m(E.call(z(this)))}}),document.registerElement){var F=document.registerElement;b.prototype.registerElement=function(b,c){function d(a){return a?void(this.impl=a):c.extends?document.createElement(c.extends,b):document.createElement(b)}var e=c.prototype;if(a.nativePrototypeTable.get(e))throw new Error("NotSupportedError");for(var f,g=Object.getPrototypeOf(e),h=[];g&&!(f=a.nativePrototypeTable.get(g));)h.push(g),g=Object.getPrototypeOf(g);if(!f)throw new Error("NotSupportedError");for(var i=Object.create(f),j=h.length-1;j>=0;j--)i=Object.create(i);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(a){var b=e[a];b&&(i[a]=function(){A(this)instanceof d||y(this),b.apply(A(this),arguments)})});var k={prototype:i};c.extends&&(k.extends=c.extends),d.prototype=e,d.prototype.constructor=d,a.constructorTable.set(i,d),a.nativePrototypeTable.set(e,i);F.call(z(this),b,k);return d},t([window.HTMLDocument||window.Document],["registerElement"])}t([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"].concat(u)),t([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById","getSelection"]),v(b.prototype,j),v(b.prototype,l),v(b.prototype,n),v(b.prototype,{get implementation(){var a=C.get(this);return a?a:(a=new g(z(this).implementation),C.set(this,a),a)}}),w(window.Document,b,document.implementation.createHTMLDocument("")),window.HTMLDocument&&w(window.HTMLDocument,b),B([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),h(g,"createDocumentType"),h(g,"createDocument"),h(g,"createHTMLDocument"),i(g,"hasFeature"),w(window.DOMImplementation,g),t([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),a.adoptNodeNoRemove=d,a.wrappers.DOMImplementation=g,a.wrappers.Document=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.wrappers.Selection,e=a.mixin,f=a.registerWrapper,g=a.renderAllPending,h=a.unwrap,i=a.unwrapIfNeeded,j=a.wrap,k=window.Window,l=window.getComputedStyle,m=window.getSelection;b.prototype=Object.create(c.prototype),k.prototype.getComputedStyle=function(a,b){return j(this||window).getComputedStyle(i(a),b)},k.prototype.getSelection=function(){return j(this||window).getSelection()},delete window.getComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(a){k.prototype[a]=function(){var b=j(this||window);return b[a].apply(b,arguments)},delete window[a]}),e(b.prototype,{getComputedStyle:function(a,b){return g(),l.call(h(this),i(a),b)},getSelection:function(){return g(),new d(m.call(h(this)))}}),f(k,b),a.wrappers.Window=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.unwrap,c=window.DataTransfer||window.Clipboard,d=c.prototype.setDragImage;c.prototype.setDragImage=function(a,c,e){d.call(this,b(a),c,e)}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=c[a],d=window[b];if(d){var e=document.createElement(a),f=e.constructor;window[b]=f}}var c=(a.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(c).forEach(b),Object.getOwnPropertyNames(a.wrappers).forEach(function(b){window[b]=a.wrappers[b]})}(window.ShadowDOMPolyfill),function(){window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded,Object.defineProperty(Element.prototype,"webkitShadowRoot",Object.getOwnPropertyDescriptor(Element.prototype,"shadowRoot"));var a=Element.prototype.createShadowRoot;Element.prototype.createShadowRoot=function(){var b=a.call(this);return CustomElements.watchShadow(this),b},Element.prototype.webkitCreateShadowRoot=Element.prototype.createShadowRoot}(),function(a){function b(a,b){var c="";return Array.prototype.forEach.call(a,function(a){c+=a.textContent+"\n\n"}),b||(c=c.replace(l,"")),c}function c(a){var b=document.createElement("style");return b.textContent=a,b}function d(a){var b=c(a);document.head.appendChild(b);var d=[];if(b.sheet)try{d=b.sheet.cssRules}catch(e){}else console.warn("sheet not found",b);return b.parentNode.removeChild(b),d}function e(){v.initialized=!0,document.body.appendChild(v);var a=v.contentDocument,b=a.createElement("base");b.href=document.baseURI,a.head.appendChild(b)}function f(a){v.initialized||e(),document.body.appendChild(v),a(v.contentDocument),document.body.removeChild(v)}function g(a,b){if(b){var e;if(a.match("@import")&&x){var g=c(a);f(function(a){a.head.appendChild(g.impl),e=g.sheet.cssRules,b(e)})}else e=d(a),b(e)}}function h(a){a&&j().appendChild(document.createTextNode(a))}function i(a,b){var d=c(a);d.setAttribute(b,""),d.setAttribute(z,""),document.head.appendChild(d)}function j(){return w||(w=document.createElement("style"),w.setAttribute(z,""),w[z]=!0),w}var k={strictStyling:!1,registry:{},shimStyling:function(a,c,d){var e=this.prepareRoot(a,c,d),f=this.isTypeExtension(d),g=this.makeScopeSelector(c,f),h=b(e,!0);h=this.scopeCssText(h,g),a&&(a.shimmedStyle=h),this.addCssToDocument(h,c)},shimStyle:function(a,b){return this.shimCssText(a.textContent,b)},shimCssText:function(a,b){return a=this.insertDirectives(a),this.scopeCssText(a,b)},makeScopeSelector:function(a,b){return a?b?"[is="+a+"]":a:""},isTypeExtension:function(a){return a&&a.indexOf("-")<0},prepareRoot:function(a,b,c){var d=this.registerRoot(a,b,c);return this.replaceTextInStyles(d.rootStyles,this.insertDirectives),this.removeStyles(a,d.rootStyles),this.strictStyling&&this.applyScopeToContent(a,b),d.scopeStyles},removeStyles:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)c.parentNode.removeChild(c)},registerRoot:function(a,b,c){var d=this.registry[b]={root:a,name:b,extendsName:c},e=this.findStyles(a);d.rootStyles=e,d.scopeStyles=d.rootStyles;var f=this.registry[d.extendsName];return!f||a&&!a.querySelector("shadow")||(d.scopeStyles=f.scopeStyles.concat(d.scopeStyles)),d},findStyles:function(a){if(!a)return[];var b=a.querySelectorAll("style");return Array.prototype.filter.call(b,function(a){return!a.hasAttribute(A)})},applyScopeToContent:function(a,b){a&&(Array.prototype.forEach.call(a.querySelectorAll("*"),function(a){a.setAttribute(b,"")}),Array.prototype.forEach.call(a.querySelectorAll("template"),function(a){this.applyScopeToContent(a.content,b)},this))},insertDirectives:function(a){return a=this.insertPolyfillDirectivesInCssText(a),this.insertPolyfillRulesInCssText(a)},insertPolyfillDirectivesInCssText:function(a){return a=a.replace(m,function(a,b){return b.slice(0,-2)+"{"}),a.replace(n,function(a,b){return b+" {"})},insertPolyfillRulesInCssText:function(a){return a=a.replace(o,function(a,b){return b.slice(0,-1)}),a.replace(p,function(a,b,c,d){var e=a.replace(b,"").replace(c,"");return d+e})},scopeCssText:function(a,b){var c=this.extractUnscopedRulesFromCssText(a);if(a=this.insertPolyfillHostInCssText(a),a=this.convertColonHost(a),a=this.convertColonAncestor(a),a=this.convertCombinators(a),b){var a,d=this;g(a,function(c){a=d.scopeRules(c,b)})}return a=a+"\n"+c,a.trim()},extractUnscopedRulesFromCssText:function(a){for(var b,c="";b=q.exec(a);)c+=b[1].slice(0,-1)+"\n\n";for(;b=r.exec(a);)c+=b[0].replace(b[2],"").replace(b[1],b[3])+"\n\n";return c},convertColonHost:function(a){return this.convertColonRule(a,cssColonHostRe,this.colonHostPartReplacer)},convertColonAncestor:function(a){return this.convertColonRule(a,cssColonAncestorRe,this.colonAncestorPartReplacer)},convertColonRule:function(a,b,c){return a.replace(b,function(a,b,d,e){if(b=polyfillHostNoCombinator,d){for(var f,g=d.split(","),h=[],i=0,j=g.length;j>i&&(f=g[i]);i++)f=f.trim(),h.push(c(b,f,e));return h.join(",")}return b+e})},colonAncestorPartReplacer:function(a,b,c){return b.match(s)?this.colonHostPartReplacer(a,b,c):a+b+c+", "+b+" "+a+c},colonHostPartReplacer:function(a,b,c){return a+b.replace(s,"")+c},convertCombinators:function(a){for(var b=0;b<combinatorsRe.length;b++)a=a.replace(combinatorsRe[b]," ");return a},scopeRules:function(a,b){var c="";return a&&Array.prototype.forEach.call(a,function(a){a.selectorText&&a.style&&a.style.cssText?(c+=this.scopeSelector(a.selectorText,b,this.strictStyling)+" {\n	",c+=this.propertiesFromRule(a)+"\n}\n\n"):a.type===CSSRule.MEDIA_RULE?(c+="@media "+a.media.mediaText+" {\n",c+=this.scopeRules(a.cssRules,b),c+="\n}\n\n"):a.cssText&&(c+=a.cssText+"\n\n")},this),c},scopeSelector:function(a,b,c){var d=[],e=a.split(",");return e.forEach(function(a){a=a.trim(),this.selectorNeedsScoping(a,b)&&(a=c&&!a.match(polyfillHostNoCombinator)?this.applyStrictSelectorScope(a,b):this.applySimpleSelectorScope(a,b)),d.push(a)},this),d.join(", ")},selectorNeedsScoping:function(a,b){var c=this.makeScopeMatcher(b);return!a.match(c)},makeScopeMatcher:function(a){return a=a.replace(/\[/g,"\\[").replace(/\[/g,"\\]"),new RegExp("^("+a+")"+selectorReSuffix,"m")},applySimpleSelectorScope:function(a,b){return a.match(polyfillHostRe)?(a=a.replace(polyfillHostNoCombinator,b),a.replace(polyfillHostRe,b+" ")):b+" "+a},applyStrictSelectorScope:function(a,b){b=b.replace(/\[is=([^\]]*)\]/g,"$1");var c=[" ",">","+","~"],d=a,e="["+b+"]";return c.forEach(function(a){var b=d.split(a);d=b.map(function(a){var b=a.trim().replace(polyfillHostRe,"");return b&&c.indexOf(b)<0&&b.indexOf(e)<0&&(a=b.replace(/([^:]*)(:*)(.*)/,"$1"+e+"$2$3")),a}).join(a)}),d},insertPolyfillHostInCssText:function(a){return a.replace(hostRe,s).replace(colonHostRe,s).replace(colonAncestorRe,t)},propertiesFromRule:function(a){return a.style.content&&!a.style.content.match(/['"]+/)?a.style.cssText.replace(/content:[^;]*;/g,"content: '"+a.style.content+"';"):a.style.cssText},replaceTextInStyles:function(a,b){a&&b&&(a instanceof Array||(a=[a]),Array.prototype.forEach.call(a,function(a){a.textContent=b.call(this,a.textContent)},this))},addCssToDocument:function(a,b){a.match("@import")?i(a,b):h(a)}},l=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,m=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,n=/polyfill-next-selector[^}]*content\:[\s]*'([^']*)'[^}]*}([^{]*?){/gim,o=/\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,p=/(polyfill-rule)[^}]*(content\:[\s]*'([^']*)'[^;]*;)[^}]*}/gim,q=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,r=/(polyfill-unscoped-rule)[^}]*(content\:[\s]*'([^']*)'[^;]*;)[^}]*}/gim,s="-shadowcsshost",t="-shadowcssancestor",u=")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)";cssColonHostRe=new RegExp("("+s+u,"gim"),cssColonAncestorRe=new RegExp("("+t+u,"gim"),selectorReSuffix="([>\\s~+[.,{:][\\s\\S]*)?$",hostRe=/@host/gim,colonHostRe=/\:host/gim,colonAncestorRe=/\:ancestor/gim,polyfillHostNoCombinator=s+"-no-combinator",polyfillHostRe=new RegExp(s,"gim"),polyfillAncestorRe=new RegExp(t,"gim"),combinatorsRe=[/\^\^/g,/\^/g,/\/shadow\//g,/\/shadow-deep\//g];var v=document.createElement("iframe");v.style.display="none";var w,x=navigator.userAgent.match("Chrome"),y="shim-shadowdom",z="shim-shadowdom-css",A="no-shim";if(window.ShadowDOMPolyfill){h("style { display: none !important; }\n");var B=wrap(document),C=B.querySelector("head");C.insertBefore(j(),C.childNodes[0]),document.addEventListener("DOMContentLoaded",function(){var b=a.urlResolver;if(window.HTMLImports&&!HTMLImports.useNative){var c="link[rel=stylesheet]["+y+"]",d="style["+y+"]";HTMLImports.importer.documentPreloadSelectors+=","+c,HTMLImports.importer.importsPreloadSelectors+=","+c,HTMLImports.parser.documentSelectors=[HTMLImports.parser.documentSelectors,c,d].join(",");var e=HTMLImports.parser.parseGeneric;HTMLImports.parser.parseGeneric=function(a){if(!a[z]){var c=a.__importElement||a;if(!c.hasAttribute(y))return void e.call(this,a);a.__resource?(c=a.ownerDocument.createElement("style"),c.textContent=b.resolveCssText(a.__resource,a.href)):b.resolveStyle(c),c.textContent=k.shimStyle(c),c.removeAttribute(y,""),c.setAttribute(z,""),c[z]=!0,c.parentNode!==C&&(a.parentNode===C?C.replaceChild(c,a):C.appendChild(c)),c.__importParsed=!0,this.markParsingComplete(a)}};var f=HTMLImports.parser.hasResource;HTMLImports.parser.hasResource=function(a){return"link"===a.localName&&"stylesheet"===a.rel&&a.hasAttribute(y)?a.__resource:f.call(this,a)}}})}a.ShadowCSS=k}(window.Platform)):!function(){window.templateContent=window.templateContent||function(a){return a.content},window.wrap=window.unwrap=function(a){return a};var a=Element.prototype.webkitCreateShadowRoot;Element.prototype.webkitCreateShadowRoot=function(){var b=this.webkitShadowRoot,c=a.call(this);return c.olderShadowRoot=b,c.host=this,CustomElements.watchShadow(this),c},Object.defineProperties(Element.prototype,{shadowRoot:{get:function(){return this.webkitShadowRoot}},createShadowRoot:{value:function(){return this.webkitCreateShadowRoot()}}}),window.templateContent=function(a){if(window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(a),!a.content&&!a._content){for(var b=document.createDocumentFragment();a.firstChild;)b.appendChild(a.firstChild);a._content=b}return a.content||a._content}}(),function(a){"use strict";function b(a){return void 0!==m[a]}function c(){h.call(this),this._isInvalid=!0}function d(a){return""==a&&c.call(this),a.toLowerCase()}function e(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,63,96].indexOf(b)?a:encodeURIComponent(a)}function f(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,96].indexOf(b)?a:encodeURIComponent(a)}function g(a,g,h){function i(a){t.push(a)}var j=g||"scheme start",k=0,l="",r=!1,s=!1,t=[];a:for(;(a[k-1]!=o||0==k)&&!this._isInvalid;){var u=a[k];switch(j){case"scheme start":if(!u||!p.test(u)){if(g){i("Invalid scheme.");break a}l="",j="no scheme";continue}l+=u.toLowerCase(),j="scheme";break;case"scheme":if(u&&q.test(u))l+=u.toLowerCase();else{if(":"!=u){if(g){if(o==u)break a;i("Code point not allowed in scheme: "+u);break a}l="",k=0,j="no scheme";continue}if(this._scheme=l,l="",g)break a;b(this._scheme)&&(this._isRelative=!0),j="file"==this._scheme?"relative":this._isRelative&&h&&h._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==u?(query="?",j="query"):"#"==u?(this._fragment="#",j="fragment"):o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._schemeData+=e(u));break;case"no scheme":if(h&&b(h._scheme)){j="relative";continue}i("Missing scheme."),c.call(this);break;case"relative or authority":if("/"!=u||"/"!=a[k+1]){i("Expected /, got: "+u),j="relative";continue}j="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=h._scheme),o==u){this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query;break a}if("/"==u||"\\"==u)"\\"==u&&i("\\ is an invalid code point."),j="relative slash";else if("?"==u)this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query="?",j="query";else{if("#"!=u){var v=a[k+1],w=a[k+2];("file"!=this._scheme||!p.test(u)||":"!=v&&"|"!=v||o!=w&&"/"!=w&&"\\"!=w&&"?"!=w&&"#"!=w)&&(this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._path.pop()),j="relative path";continue}this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query,this._fragment="#",j="fragment"}break;case"relative slash":if("/"!=u&&"\\"!=u){"file"!=this._scheme&&(this._host=h._host,this._port=h._port),j="relative path";continue}"\\"==u&&i("\\ is an invalid code point."),j="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=u){i("Expected '/', got: "+u),j="authority ignore slashes";continue}j="authority second slash";break;case"authority second slash":if(j="authority ignore slashes","/"!=u){i("Expected '/', got: "+u);continue}break;case"authority ignore slashes":if("/"!=u&&"\\"!=u){j="authority";continue}i("Expected authority, got: "+u);break;case"authority":if("@"==u){r&&(i("@ already seen."),l+="%40"),r=!0;for(var x=0;x<l.length;x++){var y=l[x];if("	"!=y&&"\n"!=y&&"\r"!=y)if(":"!=y||null!==this._password){var z=e(y);null!==this._password?this._password+=z:this._username+=z}else this._password="";else i("Invalid whitespace in authority.")}l=""}else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){k-=l.length,l="",j="host";continue}l+=u}break;case"file host":if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){2!=l.length||!p.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?j="relative path start":(this._host=d.call(this,l),l="",j="relative path start"):j="relative path";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid whitespace in file host."):l+=u;break;case"host":case"hostname":if(":"!=u||s){if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){if(this._host=d.call(this,l),l="",j="relative path start",g)break a;continue}"	"!=u&&"\n"!=u&&"\r"!=u?("["==u?s=!0:"]"==u&&(s=!1),l+=u):i("Invalid code point in host/hostname: "+u)}else if(this._host=d.call(this,l),l="",j="port","hostname"==g)break a;break;case"port":if(/[0-9]/.test(u))l+=u;else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u||g){if(""!=l){var A=parseInt(l,10);A!=m[this._scheme]&&(this._port=A+""),l=""}if(g)break a;j="relative path start";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid code point in port: "+u):c.call(this)}break;case"relative path start":if("\\"==u&&i("'\\' not allowed in path."),j="relative path","/"!=u&&"\\"!=u)continue;break;case"relative path":if(o!=u&&"/"!=u&&"\\"!=u&&(g||"?"!=u&&"#"!=u))"	"!=u&&"\n"!=u&&"\r"!=u&&(l+=e(u));else{"\\"==u&&i("\\ not allowed in relative path.");var B;(B=n[l.toLowerCase()])&&(l=B),".."==l?(this._path.pop(),"/"!=u&&"\\"!=u&&this._path.push("")):"."==l&&"/"!=u&&"\\"!=u?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&p.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==u?(this._query="?",j="query"):"#"==u&&(this._fragment="#",j="fragment")}break;case"query":g||"#"!=u?o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._query+=f(u)):(this._fragment="#",j="fragment");break;case"fragment":o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._fragment+=u)}k++}}function h(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function i(a,b){void 0===b||b instanceof i||(b=new i(String(b))),this._url=a,h.call(this);var c=a.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");g.call(this,c,null,b)}var j=!1;if(!a.forceJURL)try{var k=new URL("b","http://a");j="http://a/b"===k.href}catch(l){}if(!j){var m=Object.create(null);m.ftp=21,m.file=0,m.gopher=70,m.http=80,m.https=443,m.ws=80,m.wss=443;var n=Object.create(null);n["%2e"]=".",n[".%2e"]="..",n["%2e."]="..",n["%2e%2e"]="..";var o=void 0,p=/[a-zA-Z]/,q=/[a-zA-Z0-9\+\-\.]/;i.prototype={get href(){if(this._isInvalid)return this._url;var a="";return(""!=this._username||null!=this._password)&&(a=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+a+this.host:"")+this.pathname+this._query+this._fragment},set href(a){h.call(this),g.call(this,a)},get protocol(){return this._scheme+":"},set protocol(a){this._isInvalid||g.call(this,a+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"host")},get hostname(){return this._host},set hostname(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"hostname")},get port(){return this._port},set port(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(a){!this._isInvalid&&this._isRelative&&(this._path=[],g.call(this,a,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(a){!this._isInvalid&&this._isRelative&&(this._query="?","?"==a[0]&&(a=a.slice(1)),g.call(this,a,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(a){this._isInvalid||(this._fragment="#","#"==a[0]&&(a=a.slice(1)),g.call(this,a,"fragment"))}},a.URL=i}}(window),function(a){function b(a){for(var b=a||{},d=1;d<arguments.length;d++){var e=arguments[d];try{for(var f in e)c(f,e,b)}catch(g){}}return b}function c(a,b,c){var e=d(b,a);Object.defineProperty(c,a,e)}function d(a,b){if(a){var c=Object.getOwnPropertyDescriptor(a,b);return c||d(Object.getPrototypeOf(a),b)}}Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,c=Array.prototype.slice.call(arguments,1);return function(){var d=c.slice();return d.push.apply(d,arguments),b.apply(a,d)}}),a.mixin=b}(window.Platform),function(a){"use strict";function b(a,b,c){var d="string"==typeof a?document.createElement(a):a.cloneNode(!0);if(d.innerHTML=b,c)for(var e in c)d.setAttribute(e,c[e]);return d}var c=DOMTokenList.prototype.add,d=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){for(var a=0;a<arguments.length;a++)c.call(this,arguments[a])},DOMTokenList.prototype.remove=function(){for(var a=0;a<arguments.length;a++)d.call(this,arguments[a])},DOMTokenList.prototype.toggle=function(a,b){1==arguments.length&&(b=!this.contains(a)),b?this.add(a):this.remove(a)},DOMTokenList.prototype.switch=function(a,b){a&&this.remove(a),b&&this.add(b)};var e=function(){return Array.prototype.slice.call(this)},f=window.NamedNodeMap||window.MozNamedAttrMap||{};if(NodeList.prototype.array=e,f.prototype.array=e,HTMLCollection.prototype.array=e,!window.performance){var g=Date.now();window.performance={now:function(){return Date.now()-g}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var a=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return a?function(b){return a(function(){b(performance.now())})}:function(a){return window.setTimeout(a,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(a){clearTimeout(a)}}());var h=[],i=function(){h.push(arguments)};window.Polymer=i,a.deliverDeclarations=function(){return a.deliverDeclarations=function(){throw"Possible attempt to load Polymer twice"},h},window.addEventListener("DOMContentLoaded",function(){window.Polymer===i&&(window.Polymer=function(){console.error('You tried to use polymer without loading it first. To load polymer, <link rel="import" href="components/polymer/polymer.html">')})}),a.createDOM=b}(window.Platform),window.templateContent=window.templateContent||function(a){return a.content},function(a){a=a||(window.Inspector={});var b;window.sinspect=function(a,d){b||(b=window.open("","ShadowDOM Inspector",null,!0),b.document.write(c),b.api={shadowize:shadowize}),f(a||wrap(document.body),d)};var c=["<!DOCTYPE html>","<html>","  <head>","    <title>ShadowDOM Inspector</title>","    <style>","      body {","      }","      pre {",'        font: 9pt "Courier New", monospace;',"        line-height: 1.5em;","      }","      tag {","        color: purple;","      }","      ul {","         margin: 0;","         padding: 0;","         list-style: none;","      }","      li {","         display: inline-block;","         background-color: #f1f1f1;","         padding: 4px 6px;","         border-radius: 4px;","         margin-right: 4px;","      }","    </style>","  </head>","  <body>",'    <ul id="crumbs">',"    </ul>",'    <div id="tree"></div>',"  </body>","</html>"].join("\n"),d=[],e=function(){var a=b.document,c=a.querySelector("#crumbs");
-c.textContent="";for(var e,g=0;e=d[g];g++){var h=a.createElement("a");h.href="#",h.textContent=e.localName,h.idx=g,h.onclick=function(a){for(var b;d.length>this.idx;)b=d.pop();f(b.shadow||b,b),a.preventDefault()},c.appendChild(a.createElement("li")).appendChild(h)}},f=function(a,c){var f=b.document;k=[];var g=c||a;d.push(g),e(),f.body.querySelector("#tree").innerHTML="<pre>"+j(a,a.childNodes)+"</pre>"},g=Array.prototype.forEach.call.bind(Array.prototype.forEach),h={STYLE:1,SCRIPT:1,"#comment":1,TEMPLATE:1},i=function(a){return h[a.nodeName]},j=function(a,b,c){if(i(a))return"";var d=c||"";if(a.localName||11==a.nodeType){var e=a.localName||"shadow-root",f=d+l(a);"content"==e&&(b=a.getDistributedNodes()),f+="<br/>";var h=d+"&nbsp;&nbsp;";g(b,function(a){f+=j(a,a.childNodes,h)}),f+=d,{br:1}[e]||(f+="<tag>&lt;/"+e+"&gt;</tag>",f+="<br/>")}else{var k=a.textContent.trim();f=k?d+'"'+k+'"<br/>':""}return f},k=[],l=function(a){var b="<tag>&lt;",c=a.localName||"shadow-root";return a.webkitShadowRoot||a.shadowRoot?(b+=' <button idx="'+k.length+'" onclick="api.shadowize.call(this)">'+c+"</button>",k.push(a)):b+=c||"shadow-root",a.attributes&&g(a.attributes,function(a){b+=" "+a.name+(a.value?'="'+a.value+'"':"")}),b+="&gt;</tag>"};shadowize=function(){var a=Number(this.attributes.idx.value),b=k[a];b?f(b.webkitShadowRoot||b.shadowRoot,b):(console.log("bad shadowize node"),console.dir(this))},a.output=j}(window.Inspector),function(){var a=document.createElement("style");a.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; } \n";var b=document.querySelector("head");b.insertBefore(a,b.firstChild)}(Platform),function(a){function b(a,b){return b=b||[],b.map||(b=[b]),a.apply(this,b.map(d))}function c(a,c,d){var e;switch(arguments.length){case 0:return;case 1:e=null;break;case 2:e=c.apply(this);break;default:e=b(d,c)}f[a]=e}function d(a){return f[a]}function e(a,c){HTMLImports.whenImportsReady(function(){b(c,a)})}var f={};a.marshal=d,a.module=c,a.using=e}(window),function(a){function b(a){f.textContent=d++,e.push(a)}function c(){for(;e.length;)e.shift()()}var d=0,e=[],f=document.createTextNode("");new(window.MutationObserver||JsMutationObserver)(c).observe(f,{characterData:!0}),a.endOfMicrotask=b}(Platform),function(a){function b(a,b,d){return a.replace(d,function(a,d,e,f){var g=e.replace(/["']/g,"");return g=c(b,g),d+"'"+g+"'"+f})}function c(a,b){var c=new URL(b,a);return d(c.href)}function d(a){var b=document.baseURI,c=new URL(a,b);return c.host===b.host&&c.port===b.port&&c.protocol===b.protocol?e(b.pathname,c.pathname):a}function e(a,b){for(var c=a.split("/"),d=b.split("/");c.length&&c[0]===d[0];)c.shift(),d.shift();for(var e=0,f=c.length-1;f>e;e++)d.unshift("..");return d.join("/")}var f={resolveDom:function(a,b){b=b||a.ownerDocument.baseURI,this.resolveAttributes(a,b),this.resolveStyles(a,b);var c=a.querySelectorAll("template");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)d.content&&this.resolveDom(d.content,b)},resolveTemplate:function(a){this.resolveDom(a.content,a.ownerDocument.baseURI)},resolveStyles:function(a,b){var c=a.querySelectorAll("style");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveStyle(d,b)},resolveStyle:function(a,b){b=b||a.ownerDocument.baseURI,a.textContent=this.resolveCssText(a.textContent,b)},resolveCssText:function(a,c){return a=b(a,c,g),b(a,c,h)},resolveAttributes:function(a,b){a.hasAttributes&&a.hasAttributes()&&this.resolveElementAttributes(a,b);var c=a&&a.querySelectorAll(j);if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveElementAttributes(d,b)},resolveElementAttributes:function(a,b){b=b||a.ownerDocument.baseURI,i.forEach(function(d){var e=a.attributes[d];if(e&&e.value&&e.value.search(k)<0){var f=c(b,e.value);e.value=f}})}},g=/(url\()([^)]*)(\))/g,h=/(@import[\s]+(?!url\())([^;]*)(;)/g,i=["href","src","action"],j="["+i.join("],[")+"]",k="{{.*}}";a.urlResolver=f}(Platform),function(a){function b(a){u.push(a),t||(t=!0,q(d))}function c(a){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(a)||a}function d(){t=!1;var a=u;u=[],a.sort(function(a,b){return a.uid_-b.uid_});var b=!1;a.forEach(function(a){var c=a.takeRecords();e(a),c.length&&(a.callback_(c,a),b=!0)}),b&&d()}function e(a){a.nodes_.forEach(function(b){var c=p.get(b);c&&c.forEach(function(b){b.observer===a&&b.removeTransientObservers()})})}function f(a,b){for(var c=a;c;c=c.parentNode){var d=p.get(c);if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.options;if(c===a||g.subtree){var h=b(g);h&&f.enqueue(h)}}}}function g(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++v}function h(a,b){this.type=a,this.target=b,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function i(a){var b=new h(a.type,a.target);return b.addedNodes=a.addedNodes.slice(),b.removedNodes=a.removedNodes.slice(),b.previousSibling=a.previousSibling,b.nextSibling=a.nextSibling,b.attributeName=a.attributeName,b.attributeNamespace=a.attributeNamespace,b.oldValue=a.oldValue,b}function j(a,b){return w=new h(a,b)}function k(a){return x?x:(x=i(w),x.oldValue=a,x)}function l(){w=x=void 0}function m(a){return a===x||a===w}function n(a,b){return a===b?a:x&&m(a)?x:null}function o(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var p=new WeakMap,q=window.msSetImmediate;if(!q){var r=[],s=String(Math.random());window.addEventListener("message",function(a){if(a.data===s){var b=r;r=[],b.forEach(function(a){a()})}}),q=function(a){r.push(a),window.postMessage(s,"*")}}var t=!1,u=[],v=0;g.prototype={observe:function(a,b){if(a=c(a),!b.childList&&!b.attributes&&!b.characterData||b.attributeOldValue&&!b.attributes||b.attributeFilter&&b.attributeFilter.length&&!b.attributes||b.characterDataOldValue&&!b.characterData)throw new SyntaxError;var d=p.get(a);d||p.set(a,d=[]);for(var e,f=0;f<d.length;f++)if(d[f].observer===this){e=d[f],e.removeListeners(),e.options=b;break}e||(e=new o(this,a,b),d.push(e),this.nodes_.push(a)),e.addListeners()},disconnect:function(){this.nodes_.forEach(function(a){for(var b=p.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){d.removeListeners(),b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}};var w,x;o.prototype={enqueue:function(a){var c=this.observer.records_,d=c.length;if(c.length>0){var e=c[d-1],f=n(e,a);if(f)return void(c[d-1]=f)}else b(this.observer);c[d]=a},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(a){var b=this.options;b.attributes&&a.addEventListener("DOMAttrModified",this,!0),b.characterData&&a.addEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.addEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(a){var b=this.options;b.attributes&&a.removeEventListener("DOMAttrModified",this,!0),b.characterData&&a.removeEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.removeEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(a){if(a!==this.target){this.addListeners_(a),this.transientObservedNodes.push(a);var b=p.get(a);b||p.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[],a.forEach(function(a){this.removeListeners_(a);for(var b=p.get(a),c=0;c<b.length;c++)if(b[c]===this){b.splice(c,1);break}},this)},handleEvent:function(a){switch(a.stopImmediatePropagation(),a.type){case"DOMAttrModified":var b=a.attrName,c=a.relatedNode.namespaceURI,d=a.target,e=new j("attributes",d);e.attributeName=b,e.attributeNamespace=c;var g=a.attrChange===MutationEvent.ADDITION?null:a.prevValue;f(d,function(a){return!a.attributes||a.attributeFilter&&a.attributeFilter.length&&-1===a.attributeFilter.indexOf(b)&&-1===a.attributeFilter.indexOf(c)?void 0:a.attributeOldValue?k(g):e});break;case"DOMCharacterDataModified":var d=a.target,e=j("characterData",d),g=a.prevValue;f(d,function(a){return a.characterData?a.characterDataOldValue?k(g):e:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(a.target);case"DOMNodeInserted":var h,i,d=a.relatedNode,m=a.target;"DOMNodeInserted"===a.type?(h=[m],i=[]):(h=[],i=[m]);var n=m.previousSibling,o=m.nextSibling,e=j("childList",d);e.addedNodes=h,e.removedNodes=i,e.previousSibling=n,e.nextSibling=o,f(d,function(a){return a.childList?e:void 0})}l()}},a.JsMutationObserver=g,a.MutationObserver||(a.MutationObserver=g)}(this),window.HTMLImports=window.HTMLImports||{flags:{}},function(a){var b=(a.path,a.xhr),c=a.flags,d=function(a,b){this.cache={},this.onload=a,this.oncomplete=b,this.inflight=0,this.pending={}};d.prototype={addNodes:function(a){this.inflight+=a.length;for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)this.require(b);this.checkDone()},addNode:function(a){this.inflight++,this.require(a),this.checkDone()},require:function(a){var b=a.src||a.href;a.__nodeUrl=b,this.dedupe(b,a)||this.fetch(b,a)},dedupe:function(a,b){if(this.pending[a])return this.pending[a].push(b),!0;return this.cache[a]?(this.onload(a,b,this.cache[a]),this.tail(),!0):(this.pending[a]=[b],!1)},fetch:function(a,d){c.load&&console.log("fetch",a,d);var e=function(b,c){this.receive(a,d,b,c)}.bind(this);b.load(a,e)},receive:function(a,b,c,d){this.cache[a]=d;for(var e,f=this.pending[a],g=0,h=f.length;h>g&&(e=f[g]);g++)this.onload(a,e,d),this.tail();this.pending[a]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},b=b||{async:!0,ok:function(a){return a.status>=200&&a.status<300||304===a.status||0===a.status},load:function(c,d,e){var f=new XMLHttpRequest;return(a.flags.debug||a.flags.bust)&&(c+="?"+Math.random()),f.open("GET",c,b.async),f.addEventListener("readystatechange",function(){4===f.readyState&&d.call(e,!b.ok(f)&&f,f.response||f.responseText,c)}),f.send(),f},loadDocument:function(a,b,c){this.load(a,b,c).responseType="document"}},a.xhr=b,a.Loader=d}(window.HTMLImports),function(a){function b(a){return"link"===a.localName&&a.rel===g}function c(a){var b,c=d(a);try{b=btoa(c)}catch(e){b=btoa(unescape(encodeURIComponent(c))),console.warn("Script contained non-latin characters that were forced to latin. Some characters may be wrong.",a)}return"data:text/javascript;base64,"+b}function d(a){return a.textContent+e(a)}function e(a){var b=a.__nodeUrl;if(!b){b=a.ownerDocument.baseURI;var c="["+Math.floor(1e3*(Math.random()+1))+"]",d=a.textContent.match(/Polymer\(['"]([^'"]*)/);c=d&&d[1]||c,b+="/"+c+".js"}return"\n//# sourceURL="+b+"\n"}function f(a){var b=a.ownerDocument.createElement("style");return b.textContent=a.textContent,n.resolveUrlsInStyle(b),b}var g="import",h=a.flags,i=/Trident/.test(navigator.userAgent),j=window.ShadowDOMPolyfill?window.ShadowDOMPolyfill.wrapIfNeeded(document):document,k={documentSelectors:"link[rel="+g+"]",importsSelectors:["link[rel="+g+"]","link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},parseNext:function(){var a=this.nextToParse();a&&this.parse(a)},parse:function(a){if(this.isParsed(a))return void(h.parse&&console.log("[%s] is already parsed",a.localName));var b=this[this.map[a.localName]];b&&(this.markParsing(a),b.call(this,a))},markParsing:function(a){h.parse&&console.log("parsing",a),this.parsingElement=a},markParsingComplete:function(a){a.__importParsed=!0,a.__importElement&&(a.__importElement.__importParsed=!0),this.parsingElement=null,h.parse&&console.log("completed",a),this.parseNext()},parseImport:function(a){if(a.import.__importParsed=!0,HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(a),a.dispatchEvent(a.__resource?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),a.__pending)for(var b;a.__pending.length;)b=a.__pending.shift(),b&&b({target:a});this.markParsingComplete(a)},parseLink:function(a){b(a)?this.parseImport(a):(a.href=a.href,this.parseGeneric(a))},parseStyle:function(a){var b=a;a=f(a),a.__importElement=b,this.parseGeneric(a)},parseGeneric:function(a){this.trackElement(a),document.head.appendChild(a)},trackElement:function(a,b){var c=this,d=function(d){b&&b(d),c.markParsingComplete(a)};if(a.addEventListener("load",d),a.addEventListener("error",d),i&&"style"===a.localName){var e=!1;if(-1==a.textContent.indexOf("@import"))e=!0;else if(a.sheet){e=!0;for(var f,g=a.sheet.cssRules,h=g?g.length:0,j=0;h>j&&(f=g[j]);j++)f.type===CSSRule.IMPORT_RULE&&(e=e&&Boolean(f.styleSheet))}e&&a.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(b){var d=document.createElement("script");d.__importElement=b,d.src=b.src?b.src:c(b),a.currentScript=b,this.trackElement(d,function(){d.parentNode.removeChild(d),a.currentScript=null}),document.head.appendChild(d)},nextToParse:function(){return!this.parsingElement&&this.nextToParseInDoc(j)},nextToParseInDoc:function(a,c){for(var d,e=a.querySelectorAll(this.parseSelectorsForNode(a)),f=0,g=e.length;g>f&&(d=e[f]);f++)if(!this.isParsed(d))return this.hasResource(d)?b(d)?this.nextToParseInDoc(d.import,d):d:void 0;return c},parseSelectorsForNode:function(a){var b=a.ownerDocument||a;return b===j?this.documentSelectors:this.importsSelectors},isParsed:function(a){return a.__importParsed},hasResource:function(a){return b(a)&&!a.import?!1:!0}},l=/(url\()([^)]*)(\))/g,m=/(@import[\s]+(?!url\())([^;]*)(;)/g,n={resolveUrlsInStyle:function(a){var b=a.ownerDocument,c=b.createElement("a");return a.textContent=this.resolveUrlsInCssText(a.textContent,c),a},resolveUrlsInCssText:function(a,b){var c=this.replaceUrls(a,b,l);return c=this.replaceUrls(c,b,m)},replaceUrls:function(a,b,c){return a.replace(c,function(a,c,d,e){var f=d.replace(/["']/g,"");return b.href=f,f=b.href,c+"'"+f+"'"+e})}};a.parser=k,a.path=n,a.isIE=i}(HTMLImports),function(a){function b(a){return c(a,m)}function c(a,b){return"link"===a.localName&&a.getAttribute("rel")===b}function d(a,b){var c=a;c instanceof Document||(c=document.implementation.createHTMLDocument(m)),c._URL=b;var d=c.createElement("base");d.setAttribute("href",b),c.baseURI||(c.baseURI=b);var e=c.createElement("meta");return e.setAttribute("charset","utf-8"),c.head.appendChild(e),c.head.appendChild(d),a instanceof Document||(c.body.innerHTML=a),window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(c),c}function e(a,b){b=b||n,g(function(){h(a,b)},b)}function f(a){return"complete"===a.readyState||a.readyState===u}function g(a,b){if(f(b))a&&a();else{var c=function(){("complete"===b.readyState||b.readyState===u)&&(b.removeEventListener(v,c),g(a,b))};b.addEventListener(v,c)}}function h(a,b){function c(){f==g&&requestAnimationFrame(a)}function d(){f++,c()}var e=b.querySelectorAll("link[rel=import]"),f=0,g=e.length;if(g)for(var h,j=0;g>j&&(h=e[j]);j++)i(h)?d.call(h):(h.addEventListener("load",d),h.addEventListener("error",d));else c()}function i(a){return k?a.import&&"loading"!==a.import.readyState:a.__importParsed}var j="import"in document.createElement("link"),k=j,l=a.flags,m="import",n=window.ShadowDOMPolyfill?ShadowDOMPolyfill.wrapIfNeeded(document):document;if(k)var o={};else var p=(a.xhr,a.Loader),q=a.parser,o={documents:{},documentPreloadSelectors:"link[rel="+m+"]",importsPreloadSelectors:["link[rel="+m+"]"].join(","),loadNode:function(a){r.addNode(a)},loadSubtree:function(a){var b=this.marshalNodes(a);r.addNodes(b)},marshalNodes:function(a){return a.querySelectorAll(this.loadSelectorsForNode(a))},loadSelectorsForNode:function(a){var b=a.ownerDocument||a;return b===n?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(a,c,e){if(l.load&&console.log("loaded",a,c),c.__resource=e,b(c)){var f=this.documents[a];f||(f=d(e,a),f.__importLink=c,this.bootDocument(f),this.documents[a]=f),c.import=f}q.parseNext()},bootDocument:function(a){this.loadSubtree(a),this.observe(a),q.parseNext()},loadedAll:function(){q.parseNext()}},r=new p(o.loaded.bind(o),o.loadedAll.bind(o));var s={get:function(){return HTMLImports.currentScript||document.currentScript},configurable:!0};if(Object.defineProperty(document,"_currentScript",s),Object.defineProperty(n,"_currentScript",s),!document.baseURI){var t={get:function(){return window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",t),Object.defineProperty(n,"baseURI",t)}var u=HTMLImports.isIE?"complete":"interactive",v="readystatechange";a.hasNative=j,a.useNative=k,a.importer=o,a.whenImportsReady=e,a.IMPORT_LINK_TYPE=m,a.isImportLoaded=i,a.importLoader=r}(window.HTMLImports),function(a){function b(a){for(var b,d=0,e=a.length;e>d&&(b=a[d]);d++)"childList"===b.type&&b.addedNodes.length&&c(b.addedNodes)}function c(a){for(var b,e=0,g=a.length;g>e&&(b=a[e]);e++)d(b)&&f.loadNode(b),b.children&&b.children.length&&c(b.children)}function d(a){return 1===a.nodeType&&g.call(a,f.loadSelectorsForNode(a))}function e(a){h.observe(a,{childList:!0,subtree:!0})}var f=(a.IMPORT_LINK_TYPE,a.importer),g=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector,h=new MutationObserver(b);a.observe=e,f.observe=e}(HTMLImports),function(){function a(){HTMLImports.importer.bootDocument(b)}"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a,b){var c=document.createEvent("HTMLEvents");return c.initEvent(a,b.bubbles===!1?!1:!0,b.cancelable===!1?!1:!0,b.detail),c});var b=window.ShadowDOMPolyfill?window.ShadowDOMPolyfill.wrapIfNeeded(document):document;HTMLImports.whenImportsReady(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime(),b.dispatchEvent(new CustomEvent("HTMLImportsLoaded",{bubbles:!0}))}),HTMLImports.useNative||("complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?a():document.addEventListener("DOMContentLoaded",a))}(),window.CustomElements=window.CustomElements||{flags:{}},function(a){function b(a,c,d){var e=a.firstElementChild;if(!e)for(e=a.firstChild;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;for(;e;)c(e,d)!==!0&&b(e,c,d),e=e.nextElementSibling;return null}function c(a,b){for(var c=a.shadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:void c(a,d)}),c(a,d)}function e(a){return h(a)?(i(a),!0):void l(a)}function f(a){d(a,function(a){return e(a)?!0:void 0})}function g(a){return e(a)||f(a)}function h(b){if(!b.__upgraded__&&b.nodeType===Node.ELEMENT_NODE){var c=b.getAttribute("is")||b.localName,d=a.registry[c];if(d)return A.dom&&console.group("upgrade:",b.localName),a.upgrade(b),A.dom&&console.groupEnd(),!0}}function i(a){l(a),r(a)&&d(a,function(a){l(a)})}function j(a){if(E.push(a),!D){D=!0;var b=window.Platform&&window.Platform.endOfMicrotask||setTimeout;b(k)}}function k(){D=!1;for(var a,b=E,c=0,d=b.length;d>c&&(a=b[c]);c++)a();E=[]}function l(a){C?j(function(){m(a)}):m(a)}function m(a){(a.attachedCallback||a.detachedCallback||a.__upgraded__&&A.dom)&&(A.dom&&console.group("inserted:",a.localName),r(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?A.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.attachedCallback&&(A.dom&&console.log("inserted:",a.localName),a.attachedCallback())),A.dom&&console.groupEnd())}function n(a){o(a),d(a,function(a){o(a)})}function o(a){C?j(function(){p(a)}):p(a)}function p(a){(a.attachedCallback||a.detachedCallback||a.__upgraded__&&A.dom)&&(A.dom&&console.group("removed:",a.localName),r(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?A.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.detachedCallback&&a.detachedCallback()),A.dom&&console.groupEnd())}function q(a){return window.ShadowDOMPolyfill?ShadowDOMPolyfill.wrapIfNeeded(a):a}function r(a){for(var b=a,c=q(document);b;){if(b==c)return!0;b=b.parentNode||b.host}}function s(a){if(a.shadowRoot&&!a.shadowRoot.__watched){A.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.shadowRoot;b;)t(b),b=b.olderShadowRoot}}function t(a){a.__watched||(w(a),a.__watched=!0)}function u(a){if(A.dom){var b=a[0];if(b&&"childList"===b.type&&b.addedNodes&&b.addedNodes){for(var c=b.addedNodes[0];c&&c!==document&&!c.host;)c=c.parentNode;var d=c&&(c.URL||c._URL||c.host&&c.host.localName)||"";d=d.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",a.length,d||"")}a.forEach(function(a){"childList"===a.type&&(G(a.addedNodes,function(a){a.localName&&g(a)}),G(a.removedNodes,function(a){a.localName&&n(a)}))}),A.dom&&console.groupEnd()}function v(){u(F.takeRecords()),k()}function w(a){F.observe(a,{childList:!0,subtree:!0})}function x(a){w(a)}function y(a){A.dom&&console.group("upgradeDocument: ",a.baseURI.split("/").pop()),g(a),A.dom&&console.groupEnd()}function z(a){a=q(a);for(var b,c=a.querySelectorAll("link[rel="+B+"]"),d=0,e=c.length;e>d&&(b=c[d]);d++)b.import&&b.import.__parsed&&z(b.import);y(a)}var A=window.logFlags||{},B=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",C=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;a.hasPolyfillMutations=C;var D=!1,E=[],F=new MutationObserver(u),G=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.IMPORT_LINK_TYPE=B,a.watchShadow=s,a.upgradeDocumentTree=z,a.upgradeAll=g,a.upgradeSubtree=f,a.insertedNode=i,a.observeDocument=x,a.upgradeDocument=y,a.takeRecords=v}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.registerElement: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");if(m(b))throw new Error("DuplicateDefinitionError: a type with name '"+String(b)+"' is already registered");if(!g.prototype)throw new Error("Options missing required prototype property");return g.__name=b.toLowerCase(),g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),n(g.__name,g),g.ctor=o(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeDocumentTree(document),g.ctor}function c(a){var b=m(a);return b?c(b.extends).concat([b]):[]}function d(a){for(var b,c=a.extends,d=0;b=a.ancestry[d];d++)c=b.is&&b.tag;a.tag=c||a.__name,c&&(a.is=a.__name)}function e(a){if(!Object.__proto__){var b=HTMLElement.prototype;if(a.is){var c=document.createElement(a.tag);b=Object.getPrototypeOf(c)}for(var d,e=a.prototype;e&&e!==b;){var d=Object.getPrototypeOf(e);e.__proto__=d,e=d}}a.native=b}function f(a){return g(z(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),b.removeAttribute("unresolved"),h(b,c),b.__upgraded__=!0,j(b),a.insertedNode(b),a.upgradeSubtree(b),b}function h(a,b){Object.__proto__?a.__proto__=b.prototype:(i(a,b.prototype,b.native),a.__proto__=b.prototype)}function i(a,b,c){for(var d={},e=b;e!==c&&e!==HTMLElement.prototype;){for(var f,g=Object.getOwnPropertyNames(e),h=0;f=g[h];h++)d[f]||(Object.defineProperty(a,f,Object.getOwnPropertyDescriptor(e,f)),d[f]=1);e=Object.getPrototypeOf(e)}}function j(a){a.createdCallback&&a.createdCallback()}function k(a){if(!a.setAttribute._polyfilled){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a){l.call(this,a,null,c)},a.setAttribute._polyfilled=!0}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments);var e=this.getAttribute(a);this.attributeChangedCallback&&e!==d&&this.attributeChangedCallback(a,d,e)}function m(a){return a?x[a.toLowerCase()]:void 0}function n(a,b){x[a]=b}function o(a){return function(){return f(a)}}function p(a,b,c){return a===y?q(b,c):A(a,b)}function q(a,b){var c=m(b||a);if(c){if(a==c.tag&&b==c.is)return new c.ctor;if(!b&&!c.is)return new c.ctor}if(b){var d=q(a);return d.setAttribute("is",b),d}var d=z(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function r(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=m(b||a.localName);if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return g(a,c)}}}function s(b){var c=B.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var t=a.flags,u=Boolean(document.registerElement),v=!t.register&&u&&!window.ShadowDOMPolyfill;if(v){var w=function(){};a.registry={},a.upgradeElement=w,a.watchShadow=w,a.upgrade=w,a.upgradeAll=w,a.upgradeSubtree=w,a.observeDocument=w,a.upgradeDocument=w,a.upgradeDocumentTree=w,a.takeRecords=w}else{var x={},y="http://www.w3.org/1999/xhtml",z=document.createElement.bind(document),A=document.createElementNS.bind(document),B=Node.prototype.cloneNode;document.registerElement=b,document.createElement=q,document.createElementNS=p,Node.prototype.cloneNode=s,a.registry=x,a.upgrade=r}var C;C=Object.__proto__||v?function(a,b){return a instanceof b}:function(a,b){for(var c=a;c;){if(c===b.prototype)return!0;c=c.__proto__}return!1},a.instanceof=C,document.register=document.registerElement,a.hasNative=u,a.useNative=v}(window.CustomElements),function(a){function b(a){return"link"===a.localName&&a.getAttribute("rel")===c}var c=a.IMPORT_LINK_TYPE,d={selectors:["link[rel="+c+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(d.selectors);e(b,function(a){d[d.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(a){b(a)&&this.parseImport(a)},parseImport:function(a){a.import&&d.parse(a.import)}},e=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.parser=d,a.IMPORT_LINK_TYPE=c}(window.CustomElements),function(a){function b(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document);var a=window.Platform&&Platform.endOfMicrotask?Platform.endOfMicrotask:setTimeout;a(function(){CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0})),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(a){CustomElements.parser.parse(a.import)})})}if("function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a){var b=document.createEvent("HTMLEvents");return b.initEvent(a,!0,!0),b}),"complete"===document.readyState||a.flags.eager)b();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var c=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(c,b)}else b()}(window.CustomElements),function(){if(window.ShadowDOMPolyfill){var a=["upgradeAll","upgradeSubtree","observeDocument","upgradeDocument"],b={};a.forEach(function(a){b[a]=CustomElements[a]}),a.forEach(function(a){CustomElements[a]=function(c){return b[a](wrap(c))}})}}(),function(a){function b(a){this.regex=a}var c=a.endOfMicrotask;b.prototype={extractUrls:function(a,b){for(var c,d,e=[];c=this.regex.exec(a);)d=new URL(c[1],b),e.push({matched:c[0],url:d.href});return e},process:function(a,b,c){var d=this.extractUrls(a,b);this.fetch(d,{},c)},fetch:function(a,b,d){var e=a.length;if(!e)return d(b);for(var f,g,h,i=function(){0===--e&&d(b)},j=function(a,c){var d=c.match,e=d.url;if(a)return b[e]="",i();var f=c.response||c.responseText;b[e]=f,this.fetch(this.extractUrls(f,e),b,i)},k=0;e>k;k++)f=a[k],h=f.url,b[h]?c(i):(g=this.xhr(h,j,this),g.match=f,b[h]=g)},xhr:function(a,b,c){var d=new XMLHttpRequest;return d.open("GET",a,!0),d.send(),d.onload=function(){b.call(c,null,d)},d.onerror=function(){b.call(c,null,d)},d}},a.Loader=b}(window.Platform),function(a){function b(){this.loader=new d(this.regex)}var c=a.urlResolver,d=a.Loader;b.prototype={regex:/@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,resolve:function(a,b,c){var d=function(d){c(this.flatten(a,b,d))}.bind(this);this.loader.process(a,b,d)},resolveNode:function(a,b){var c=a.textContent,d=a.ownerDocument.baseURI,e=function(c){a.textContent=c,b(a)};this.resolve(c,d,e)},flatten:function(a,b,d){for(var e,f,g,h=this.loader.extractUrls(a,b),i=0;i<h.length;i++)e=h[i],f=e.url,g=c.resolveCssText(d[f],f),g=this.flatten(g,f,d),a=a.replace(e.matched,g);return a},loadStyles:function(a,b){function c(){e++,e===f&&b&&b()}for(var d,e=0,f=a.length,g=0;f>g&&(d=a[g]);g++)this.resolveNode(d,c)}};var e=new b;a.styleResolver=e}(window.Platform),function(a){a=a||{},a.external=a.external||{};var b={shadow:function(a){return a?a.shadowRoot||a.webkitShadowRoot:void 0},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);return this.canTarget(b)?b:void 0},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d}e=this.olderShadow(e)}return f}},owner:function(a){for(var b=a;b.parentNode;)b=b.parentNode;return b.nodeType!=Node.DOCUMENT_NODE&&b.nodeType!=Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target);return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}};a.targetFinding=b,a.findTarget=b.findTarget.bind(b),window.PointerEventsPolyfill=a}(window.PointerEventsPolyfill),function(){function a(a){return"body ^^ "+b(a)}function b(a){return'[touch-action="'+a+'"]'}function c(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; touch-action-delay: none; }"}var d=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],e="";d.forEach(function(d){String(d)===d?(e+=b(d)+c(d)+"\n",e+=a(d)+c(d)+"\n"):(e+=d.selectors.map(b)+c(d.rule)+"\n",e+=d.selectors.map(a)+c(d.rule)+"\n")});var f=document.createElement("style");f.textContent=e,document.head.appendChild(f)}(),function(a){function b(a,e){e=e||{};var f=e.buttons;if(!d&&!f&&"touch"!==a)switch(e.which){case 1:f=1;break;case 2:f=4;break;case 3:f=2;break;default:f=0}var i;if(c)i=new MouseEvent(a,e);else{i=document.createEvent("MouseEvent");for(var j,k={},l=0;l<g.length;l++)j=g[l],k[j]=e[j]||h[l];i.initMouseEvent(a,k.bubbles,k.cancelable,k.view,k.detail,k.screenX,k.screenY,k.clientX,k.clientY,k.ctrlKey,k.altKey,k.shiftKey,k.metaKey,k.button,k.relatedTarget)}i.__proto__=b.prototype,d||Object.defineProperty(i,"buttons",{get:function(){return f},enumerable:!0});var m=0;return m=e.pressure?e.pressure:f?.5:0,Object.defineProperties(i,{pointerId:{value:e.pointerId||0,enumerable:!0},width:{value:e.width||0,enumerable:!0},height:{value:e.height||0,enumerable:!0},pressure:{value:m,enumerable:!0},tiltX:{value:e.tiltX||0,enumerable:!0},tiltY:{value:e.tiltY||0,enumerable:!0},pointerType:{value:e.pointerType||"",enumerable:!0},hwTimestamp:{value:e.hwTimestamp||0,enumerable:!0},isPrimary:{value:e.isPrimary||!1,enumerable:!0}}),i}var c=!1,d=!1;try{var e=new MouseEvent("click",{buttons:1});c=!0,d=1===e.buttons,e=null}catch(f){}var g=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget"],h=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null];b.prototype=Object.create(MouseEvent.prototype),a.PointerEvent||(a.PointerEvent=b)}(window),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);
-c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PointerEventsPolyfill),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0],d="undefined"!=typeof SVGElementInstance,e={targets:new WeakMap,handledEvents:new WeakMap,pointermap:new a.PointerMap,eventMap:{},eventSources:{},eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.unregister.call(b,a)},contains:a.external.contains||function(a,b){return a.contains(b)},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.contains(a.target,a.relatedTarget)||this.leave(a)},enterOver:function(a){this.over(a),this.contains(a.target,a.relatedTarget)||this.enter(a)},eventHandler:function(a){if(!this.handledEvents.get(a)){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),this.handledEvents.set(a,!0)}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:a.external.addEvent||function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:a.external.removeEvent||function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(a,b){this.captureInfo&&(b.relatedTarget=null);var c=new PointerEvent(a,b);return b.preventDefault&&(c.preventDefault=b.preventDefault),this.targets.set(c,this.targets.get(b)||b.target),c},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var e,f={},g=0;g<b.length;g++)e=b[g],f[e]=a[e]||c[g],!d||"target"!==e&&"relatedTarget"!==e||f[e]instanceof SVGElementInstance&&(f[e]=f[e].correspondingUseElement);return a.preventDefault&&(f.preventDefault=function(){a.preventDefault()}),f},getTarget:function(a){return this.captureInfo&&this.captureInfo.id===a.pointerId?this.captureInfo.target:this.targets.get(a)},setCapture:function(a,b){this.captureInfo&&this.releaseCapture(this.captureInfo.id),this.captureInfo={id:a,target:b};var c=new PointerEvent("gotpointercapture",{bubbles:!0});this.implicitRelease=this.releaseCapture.bind(this,a),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease),this.targets.set(c,b),this.asyncDispatchEvent(c)},releaseCapture:function(a){if(this.captureInfo&&this.captureInfo.id===a){var b=new PointerEvent("lostpointercapture",{bubbles:!0}),c=this.captureInfo.target;this.captureInfo=null,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease),this.targets.set(b,c),this.asyncDispatchEvent(b)}},dispatchEvent:a.external.dispatchEvent||function(a){var b=this.getTarget(a);return b?b.dispatchEvent(a):void 0},asyncDispatchEvent:function(a){setTimeout(this.dispatchEvent.bind(this,a),0)}};e.boundHandler=e.eventHandler.bind(e),a.dispatcher=e,a.register=e.register.bind(e),a.unregister=e.unregister.bind(e)}(window.PointerEventsPolyfill),function(a){function b(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),g&&(this.observer=new g(this.mutationWatcher.bind(this)))}var c=Array.prototype.forEach.call.bind(Array.prototype.forEach),d=Array.prototype.map.call.bind(Array.prototype.map),e=Array.prototype.slice.call.bind(Array.prototype.slice),f=Array.prototype.filter.call.bind(Array.prototype.filter),g=window.MutationObserver||window.WebKitMutationObserver,h="[touch-action]",i={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};b.prototype={watchSubtree:function(b){a.targetFinding.canTarget(b)&&this.observer.observe(b,i)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){c(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(h):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(e(b))},installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){var b=d(a,this.findElements,this);return b.push(f(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}},g||(b.prototype.watchSubtree=function(){console.warn("PointerEventsPolyfill: MutationObservers not found, touch-action will not be dynamically detected")}),a.Installer=b}(window.PointerEventsPolyfill),function(a){var b=a.dispatcher,c=b.pointermap,d=25,e={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){b.listen(a,this.events)},unregister:function(a){b.unlisten(a,this.events)},lastTouches:[],isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,e=a.clientX,f=a.clientY,g=0,h=c.length;h>g&&(b=c[g]);g++){var i=Math.abs(e-b.x),j=Math.abs(f-b.y);if(d>=i&&d>=j)return!0}},prepareEvent:function(a){var c=b.cloneEvent(a),d=c.preventDefault;return c.preventDefault=function(){a.preventDefault(),d()},c.pointerId=this.POINTER_ID,c.isPrimary=!0,c.pointerType=this.POINTER_TYPE,c},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.has(this.POINTER_ID);d&&this.cancel(a);var e=this.prepareEvent(a);c.set(this.POINTER_ID,a),b.down(e)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var c=this.prepareEvent(a);b.move(c)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.get(this.POINTER_ID);if(d&&d.button===a.button){var e=this.prepareEvent(a);b.up(e),this.cleanupMouse()}}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var c=this.prepareEvent(a);b.enterOver(c)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var c=this.prepareEvent(a);b.leaveOut(c)}},cancel:function(a){var c=this.prepareEvent(a);b.cancel(c),this.cleanupMouse()},cleanupMouse:function(){c["delete"](this.POINTER_ID)}};a.mouseEvents=e}(window.PointerEventsPolyfill),function(a){var b,c=a.dispatcher,d=a.findTarget,e=a.targetFinding.allShadows.bind(a.targetFinding),f=c.pointermap,g=Array.prototype.map.call.bind(Array.prototype.map),h=2500,i=200,j="touch-action",k=!1,l={scrollType:new WeakMap,events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){k?c.listen(a,this.events):b.enableOnSubtree(a)},unregister:function(a){k&&c.unlisten(a,this.events)},elementAdded:function(a){var b=a.getAttribute(j),d=this.touchActionToScrollType(b);d&&(this.scrollType.set(a,d),c.listen(a,this.events),e(a).forEach(function(a){this.scrollType.set(a,d),c.listen(a,this.events)},this))},elementRemoved:function(a){this.scrollType["delete"](a),c.unlisten(a,this.events),e(a).forEach(function(a){this.scrollType["delete"](a),c.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(j),d=this.touchActionToScrollType(c),f=this.touchActionToScrollType(b);d&&f?(this.scrollType.set(a,d),e(a).forEach(function(a){this.scrollType.set(a,d)},this)):f?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){(0===f.pointers()||1===f.pointers()&&f.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,i)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return("touchstart"===a||"touchmove"===a)&&(b=1),b},touchToPointer:function(a){var b=c.cloneEvent(a);return b.pointerId=a.identifier+2,b.target=d(b),b.bubbles=!0,b.cancelable=!0,b.detail=this.clickCount,b.button=0,b.buttons=this.typeToButtons(this.currentTouchEvent),b.width=a.webkitRadiusX||a.radiusX||0,b.height=a.webkitRadiusY||a.radiusY||0,b.pressure=a.webkitForce||a.force||.5,b.isPrimary=this.isPrimaryTouch(a),b.pointerType=this.POINTER_TYPE,b},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a.type;var d=g(c,this.touchToPointer,this);d.forEach(function(b){b.preventDefault=function(){this.scrolling=!1,this.firstXY=null,a.preventDefault()}},this),d.forEach(b,this)},shouldScroll:function(a){if(this.firstXY){var b,c=this.scrollType.get(a.currentTarget);if("none"===c)b=!1;else if("XY"===c)b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]);b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)if(c.identifier===b)return!0},vacuumTouches:function(a){var b=a.touches;if(f.pointers()>=b.length){var c=[];f.forEach(function(a,d){if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(this.touchToPointer(e))}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){f.set(a.pointerId,{target:a.target,out:a,outTarget:a.target});c.over(a),c.enter(a),c.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,d=f.get(b.pointerId);if(d){var e=d.out,g=d.outTarget;c.move(b),e&&g!==b.target&&(e.relatedTarget=b.target,b.relatedTarget=g,e.target=g,b.target?(c.leaveOut(e),c.enterOver(b)):(b.target=g,b.relatedTarget=null,this.cancelOut(b))),d.out=b,d.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(c.up(a),c.out(a),c.leave(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){c.cancel(a),c.out(a),c.leave(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){f["delete"](a.pointerId),this.removePrimaryPointer(a)},dedupSynthMouse:function(b){var c=a.mouseEvents.lastTouches,d=b.changedTouches[0];if(this.isPrimaryTouch(d)){var e={x:d.clientX,y:d.clientY};c.push(e);var f=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,c,e);setTimeout(f,h)}}};k||(b=new a.Installer(l.elementAdded,l.elementRemoved,l.elementChanged,l)),a.touchEvents=l}(window.PointerEventsPolyfill),function(a){var b=a.dispatcher,c=b.pointermap,d=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,e={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){b.listen(a,this.events)},unregister:function(a){b.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var c=a;return d&&(c=b.cloneEvent(a),c.pointerType=this.POINTER_TYPES[a.pointerType]),c},cleanup:function(a){c["delete"](a)},MSPointerDown:function(a){c.set(a.pointerId,a);var d=this.prepareEvent(a);b.down(d)},MSPointerMove:function(a){var c=this.prepareEvent(a);b.move(c)},MSPointerUp:function(a){var c=this.prepareEvent(a);b.up(c),this.cleanup(a.pointerId)},MSPointerOut:function(a){var c=this.prepareEvent(a);b.leaveOut(c)},MSPointerOver:function(a){var c=this.prepareEvent(a);b.enterOver(c)},MSPointerCancel:function(a){var c=this.prepareEvent(a);b.cancel(c),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var c=b.makeEvent("lostpointercapture",a);b.dispatchEvent(c)},MSGotPointerCapture:function(a){var c=b.makeEvent("gotpointercapture",a);b.dispatchEvent(c)}};a.msEvents=e}(window.PointerEventsPolyfill),function(a){var b=a.dispatcher;if(void 0===window.navigator.pointerEnabled){if(Object.defineProperty(window.navigator,"pointerEnabled",{value:!0,enumerable:!0}),window.navigator.msPointerEnabled){var c=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:c,enumerable:!0}),b.registerSource("ms",a.msEvents)}else b.registerSource("mouse",a.mouseEvents),void 0!==window.ontouchstart&&b.registerSource("touch",a.touchEvents);b.register(document)}}(window.PointerEventsPolyfill),function(a){function b(a){if(!e.pointermap.has(a))throw new Error("InvalidPointerId")}var c,d,e=a.dispatcher,f=window.navigator;f.msPointerEnabled?(c=function(a){b(a),this.msSetPointerCapture(a)},d=function(a){b(a),this.msReleasePointerCapture(a)}):(c=function(a){b(a),e.setCapture(a,this)},d=function(a){b(a),e.releaseCapture(a,this)}),window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:c},releasePointerCapture:{value:d}})}(window.PointerEventsPolyfill),PointerGestureEvent.prototype.preventTap=function(){this.tapPrevented=!0},function(a){a=a||{},a.utils={LCA:{find:function(a,b){if(a===b)return a;if(a.contains){if(a.contains(b))return a;if(b.contains(a))return b}var c=this.depth(a),d=this.depth(b),e=c-d;for(e>0?a=this.walk(a,e):b=this.walk(b,-e);a&&b&&a!==b;)a=this.walk(a,1),b=this.walk(b,1);return a},walk:function(a,b){for(var c=0;b>c;c++)a=a.parentNode;return a},depth:function(a){for(var b=0;a;)b++,a=a.parentNode;return b}}},a.findLCA=function(b,c){return a.utils.LCA.find(b,c)},window.PointerGestures=a}(window.PointerGestures),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PointerGestures),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","screenX","screenY","pageX","pageY","tapPrevented"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],d={handledEvents:new WeakMap,targets:new WeakMap,handlers:{},recognizers:{},events:{},registerRecognizer:function(a,b){var c=b;this.recognizers[a]=c,c.events.forEach(function(a){if(c[a]){this.events[a]=!0;var b=c[a].bind(c);this.addHandler(a,b)}},this)},addHandler:function(a,b){var c=a;this.handlers[c]||(this.handlers[c]=[]),this.handlers[c].push(b)},registerTarget:function(a){this.listen(Object.keys(this.events),a)},unregisterTarget:function(a){this.unlisten(Object.keys(this.events),a)},eventHandler:function(a){if(!this.handledEvents.get(a)){var b=a.type,c=this.handlers[b];c&&this.makeQueue(c,a),this.handledEvents.set(a,!0)}},makeQueue:function(a,b){var c=this.cloneEvent(b);setTimeout(this.runQueue.bind(this,a,c),0)},runQueue:function(a,b){this.currentPointerId=b.pointerId;for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)c(b);this.currentPointerId=0},listen:function(a,b){a.forEach(function(a){this.addEvent(a,this.boundHandler,!1,b)},this)},unlisten:function(a){a.forEach(function(a){this.removeEvent(a,this.boundHandler,!1,inTarget)},this)},addEvent:function(a,b,c,d){d.addEventListener(a,b,c)},removeEvent:function(a,b,c,d){d.removeEventListener(a,b,c)},makeEvent:function(a,b){return new PointerGestureEvent(a,b)},cloneEvent:function(a){for(var d,e={},f=0;f<b.length;f++)d=b[f],e[d]=a[d]||c[f];return e},dispatchEvent:function(a,b){var c=b||this.targets.get(a);c&&(c.dispatchEvent(a),a.tapPrevented&&this.preventTap(this.currentPointerId))},asyncDispatchEvent:function(a,b){var c=function(){this.dispatchEvent(a,b)}.bind(this);setTimeout(c,0)},preventTap:function(a){var b=this.recognizers.tap;b&&b.preventTap(a)}};d.boundHandler=d.eventHandler.bind(d),d.registerQueue=[],d.immediateRegister=!1,a.dispatcher=d,a.register=function(b){if(d.immediateRegister){var c=window.PointerEventsPolyfill;c&&c.register(b),a.dispatcher.registerTarget(b)}else d.registerQueue.push(b)},a.register(document)}(window.PointerGestures),function(a){var b=a.dispatcher,c={HOLD_DELAY:200,WIGGLE_THRESHOLD:16,events:["pointerdown","pointermove","pointerup","pointercancel"],heldPointer:null,holdJob:null,pulse:function(){var a=Date.now()-this.heldPointer.timeStamp,b=this.held?"holdpulse":"hold";this.fireHold(b,a),this.held=!0},cancel:function(){clearInterval(this.holdJob),this.held&&this.fireHold("release"),this.held=!1,this.heldPointer=null,this.target=null,this.holdJob=null},pointerdown:function(a){a.isPrimary&&!this.heldPointer&&(this.heldPointer=a,this.target=a.target,this.holdJob=setInterval(this.pulse.bind(this),this.HOLD_DELAY))},pointerup:function(a){this.heldPointer&&this.heldPointer.pointerId===a.pointerId&&this.cancel()},pointercancel:function(){this.cancel()},pointermove:function(a){if(this.heldPointer&&this.heldPointer.pointerId===a.pointerId){var b=a.clientX-this.heldPointer.clientX,c=a.clientY-this.heldPointer.clientY;b*b+c*c>this.WIGGLE_THRESHOLD&&this.cancel()}},fireHold:function(a,c){var d={pointerType:this.heldPointer.pointerType,clientX:this.heldPointer.clientX,clientY:this.heldPointer.clientY};c&&(d.holdTime=c);var e=b.makeEvent(a,d);b.dispatchEvent(e,this.target),e.tapPrevented&&b.preventTap(this.heldPointer.pointerId)}};b.registerRecognizer("hold",c)}(window.PointerGestures),function(a){var b=a.dispatcher,c=new a.PointerMap,d={events:["pointerdown","pointermove","pointerup","pointercancel"],WIGGLE_THRESHOLD:4,clampDir:function(a){return a>0?1:-1},calcPositionDelta:function(a,b){var c=0,d=0;return a&&b&&(c=b.pageX-a.pageX,d=b.pageY-a.pageY),{x:c,y:d}},fireTrack:function(a,c,d){var e=d,f=this.calcPositionDelta(e.downEvent,c),g=this.calcPositionDelta(e.lastMoveEvent,c);g.x&&(e.xDirection=this.clampDir(g.x)),g.y&&(e.yDirection=this.clampDir(g.y));var h={dx:f.x,dy:f.y,ddx:g.x,ddy:g.y,clientX:c.clientX,clientY:c.clientY,pageX:c.pageX,pageY:c.pageY,screenX:c.screenX,screenY:c.screenY,xDirection:e.xDirection,yDirection:e.yDirection,trackInfo:e.trackInfo,relatedTarget:c.target,pointerType:c.pointerType},i=b.makeEvent(a,h);e.lastMoveEvent=c,b.dispatchEvent(i,e.downTarget)},pointerdown:function(a){if(a.isPrimary&&("mouse"===a.pointerType?1===a.buttons:!0)){var b={downEvent:a,downTarget:a.target,trackInfo:{},lastMoveEvent:null,xDirection:0,yDirection:0,tracking:!1};c.set(a.pointerId,b)}},pointermove:function(a){var b=c.get(a.pointerId);if(b)if(b.tracking)this.fireTrack("track",a,b);else{var d=this.calcPositionDelta(b.downEvent,a),e=d.x*d.x+d.y*d.y;e>this.WIGGLE_THRESHOLD&&(b.tracking=!0,this.fireTrack("trackstart",b.downEvent,b),this.fireTrack("track",a,b))}},pointerup:function(a){var b=c.get(a.pointerId);b&&(b.tracking&&this.fireTrack("trackend",a,b),c.delete(a.pointerId))},pointercancel:function(a){this.pointerup(a)}};b.registerRecognizer("track",d)}(window.PointerGestures),function(a){var b=a.dispatcher,c={MIN_VELOCITY:.5,MAX_QUEUE:4,moveQueue:[],target:null,pointerId:null,events:["pointerdown","pointermove","pointerup","pointercancel"],pointerdown:function(a){a.isPrimary&&!this.pointerId&&(this.pointerId=a.pointerId,this.target=a.target,this.addMove(a))},pointermove:function(a){a.pointerId===this.pointerId&&this.addMove(a)},pointerup:function(a){a.pointerId===this.pointerId&&this.fireFlick(a),this.cleanup()},pointercancel:function(){this.cleanup()},cleanup:function(){this.moveQueue=[],this.target=null,this.pointerId=null},addMove:function(a){this.moveQueue.length>=this.MAX_QUEUE&&this.moveQueue.shift(),this.moveQueue.push(a)},fireFlick:function(a){for(var c,d,e,f,g,h,i,j=a,k=this.moveQueue.length,l=0,m=0,n=0,o=0;k>o&&(i=this.moveQueue[o]);o++)c=j.timeStamp-i.timeStamp,d=j.clientX-i.clientX,e=j.clientY-i.clientY,f=d/c,g=e/c,h=Math.sqrt(f*f+g*g),h>n&&(l=f,m=g,n=h);var p=Math.abs(l)>Math.abs(m)?"x":"y",q=this.calcAngle(l,m);if(Math.abs(n)>=this.MIN_VELOCITY){var r=b.makeEvent("flick",{xVelocity:l,yVelocity:m,velocity:n,angle:q,majorAxis:p,pointerType:a.pointerType});b.dispatchEvent(r,this.target)}},calcAngle:function(a,b){return 180*Math.atan2(b,a)/Math.PI}};b.registerRecognizer("flick",c)}(window.PointerGestures),function(a){var b=a.dispatcher,c=new a.PointerMap,d=180/Math.PI,e={events:["pointerdown","pointermove","pointerup","pointercancel"],reference:{},pointerdown:function(b){if(c.set(b.pointerId,b),2==c.pointers()){var d=this.calcChord(),e=this.calcAngle(d);this.reference={angle:e,diameter:d.diameter,target:a.findLCA(d.a.target,d.b.target)}}},pointerup:function(a){c.delete(a.pointerId)},pointermove:function(a){c.has(a.pointerId)&&(c.set(a.pointerId,a),c.pointers()>1&&this.calcPinchRotate())},pointercancel:function(a){this.pointerup(a)},dispatchPinch:function(a,c){var d=a/this.reference.diameter,e=b.makeEvent("pinch",{scale:d,centerX:c.center.x,centerY:c.center.y});b.dispatchEvent(e,this.reference.target)},dispatchRotate:function(a,c){var d=Math.round((a-this.reference.angle)%360),e=b.makeEvent("rotate",{angle:d,centerX:c.center.x,centerY:c.center.y});b.dispatchEvent(e,this.reference.target)},calcPinchRotate:function(){var a=this.calcChord(),b=a.diameter,c=this.calcAngle(a);b!=this.reference.diameter&&this.dispatchPinch(b,a),c!=this.reference.angle&&this.dispatchRotate(c,a)},calcChord:function(){var a=[];c.forEach(function(b){a.push(b)});for(var b,d,e,f=0,g={a:a[0],b:a[1]},h=0;h<a.length;h++)for(var i=a[h],j=h+1;j<a.length;j++){var k=a[j];b=Math.abs(i.clientX-k.clientX),d=Math.abs(i.clientY-k.clientY),e=b+d,e>f&&(f=e,g={a:i,b:k})}return b=Math.abs(g.a.clientX+g.b.clientX)/2,d=Math.abs(g.a.clientY+g.b.clientY)/2,g.center={x:b,y:d},g.diameter=f,g},calcAngle:function(a){var b=a.a.clientX-a.b.clientX,c=a.a.clientY-a.b.clientY;return(360+Math.atan2(c,b)*d)%360}};b.registerRecognizer("pinch",e)}(window.PointerGestures),function(a){var b=a.dispatcher,c=new a.PointerMap,d={events:["pointerdown","pointermove","pointerup","pointercancel","keyup"],pointerdown:function(a){a.isPrimary&&!a.tapPrevented&&c.set(a.pointerId,{target:a.target,buttons:a.buttons,x:a.clientX,y:a.clientY})},pointermove:function(a){if(a.isPrimary){var b=c.get(a.pointerId);b&&a.tapPrevented&&c.delete(a.pointerId)}},shouldTap:function(a,b){return a.tapPrevented?void 0:"mouse"===a.pointerType?1===b.buttons:!0},pointerup:function(d){var e=c.get(d.pointerId);if(e&&this.shouldTap(d,e)){var f=a.findLCA(e.target,d.target);if(f){var g=b.makeEvent("tap",{x:d.clientX,y:d.clientY,detail:d.detail,pointerType:d.pointerType});b.dispatchEvent(g,f)}}c.delete(d.pointerId)},pointercancel:function(a){c.delete(a.pointerId)},keyup:function(a){var c=a.keyCode;if(32===c){var d=a.target;d instanceof HTMLInputElement||d instanceof HTMLTextAreaElement||b.dispatchEvent(b.makeEvent("tap",{x:0,y:0,detail:0,pointerType:"unavailable"}),d)}},preventTap:function(a){c.delete(a)}};b.registerRecognizer("tap",d)}(window.PointerGestures),function(a){function b(){c.immediateRegister=!0;var b=c.registerQueue;b.forEach(a.register),b.length=0}var c=a.dispatcher;"complete"===document.readyState?b():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&b()})}(window.PointerGestures),function(){"use strict";function a(a){for(;a.parentNode;)a=a.parentNode;return"function"==typeof a.getElementById?a:null}function b(a,b){var c=a.bindings;if(!c)return void(a.bindings={});var d=c[b];d&&(d.close(),c[b]=void 0)}function c(a){return null==a?"":a}function d(a,b){a.data=c(b)}function e(a){return function(b){return d(a,b)}}function f(a,b,d,e){return d?void(e?a.setAttribute(b,""):a.removeAttribute(b)):void a.setAttribute(b,c(e))}function g(a,b,c){return function(d){f(a,b,c,d)}}function h(a){switch(a.type){case"checkbox":return s;case"radio":case"select-multiple":case"select-one":return"change";case"range":if(/Trident|MSIE/.test(navigator.userAgent))return"change";default:return"input"}}function i(a,b,d,e){a[b]=(e||c)(d)}function j(a,b,c){return function(d){return i(a,b,d,c)}}function k(){}function l(a,b,c,d){function e(){c.setValue(a[b]),c.discardChanges(),(d||k)(a),Platform.performMicrotaskCheckpoint()}var f=h(a);a.addEventListener(f,e);var g=c.close;c.close=function(){g&&(a.removeEventListener(f,e),c.close=g,c.close(),g=void 0)}}function m(a){return Boolean(a)}function n(b){if(b.form)return r(b.form.elements,function(a){return a!=b&&"INPUT"==a.tagName&&"radio"==a.type&&a.name==b.name});var c=a(b);if(!c)return[];var d=c.querySelectorAll('input[type="radio"][name="'+b.name+'"]');return r(d,function(a){return a!=b&&!a.form})}function o(a){"INPUT"===a.tagName&&"radio"===a.type&&n(a).forEach(function(a){var b=a.bindings.checked;b&&b.setValue(!1)})}function p(a,b){var d,e,f,g=a.parentNode;g instanceof HTMLSelectElement&&g.bindings&&g.bindings.value&&(d=g,e=d.bindings.value,f=d.value),a.value=c(b),d&&d.value!=f&&(e.setValue(d.value),e.discardChanges(),Platform.performMicrotaskCheckpoint())}function q(a){return function(b){p(a,b)}}var r=Array.prototype.filter.call.bind(Array.prototype.filter);Node.prototype.bind=function(a,b){console.error("Unhandled binding to Node: ",this,a,b)},Node.prototype.unbind=function(a){b(this,a)},Node.prototype.unbindAll=function(){if(this.bindings){for(var a=Object.keys(this.bindings),b=0;b<a.length;b++){var c=this.bindings[a[b]];c&&c.close()}this.bindings={}}},Text.prototype.bind=function(a,c,f){return"textContent"!==a?Node.prototype.bind.call(this,a,c,f):f?d(this,c):(b(this,"textContent"),d(this,c.open(e(this))),this.bindings.textContent=c)},Element.prototype.bind=function(a,c,d){var e="?"==a[a.length-1];return e&&(this.removeAttribute(a),a=a.slice(0,-1)),d?f(this,a,e,c):(b(this,a),f(this,a,e,c.open(g(this,a,e))),this.bindings[a]=c)};var s;!function(){var a=document.createElement("div"),b=a.appendChild(document.createElement("input"));b.setAttribute("type","checkbox");var c,d=0;b.addEventListener("click",function(){d++,c=c||"click"}),b.addEventListener("change",function(){d++,c=c||"change"});var e=document.createEvent("MouseEvent");e.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),b.dispatchEvent(e),s=1==d?"change":c}(),HTMLInputElement.prototype.bind=function(a,d,e){if("value"!==a&&"checked"!==a)return HTMLElement.prototype.bind.call(this,a,d,e);this.removeAttribute(a);var f="checked"==a?m:c,g="checked"==a?o:k;return e?i(this,a,d,f):(b(this,a),l(this,a,d,g),i(this,a,d.open(j(this,a,f)),f),this.bindings[a]=d)},HTMLTextAreaElement.prototype.bind=function(a,d,e){return"value"!==a?HTMLElement.prototype.bind.call(this,a,d,e):(this.removeAttribute("value"),e?i(this,"value",d):(b(this,"value"),l(this,"value",d),i(this,"value",d.open(j(this,"value",c))),this.bindings.value=d))},HTMLOptionElement.prototype.bind=function(a,c,d){return"value"!==a?HTMLElement.prototype.bind.call(this,a,c,d):(this.removeAttribute("value"),d?p(this,c):(b(this,"value"),l(this,"value",c),p(this,c.open(q(this))),this.bindings.value=c))},HTMLSelectElement.prototype.bind=function(a,c,d){return"selectedindex"===a&&(a="selectedIndex"),"selectedIndex"!==a&&"value"!==a?HTMLElement.prototype.bind.call(this,a,c,d):(this.removeAttribute(a),d?i(this,a,c):(b(this,a),l(this,a,c),i(this,a,c.open(j(this,a))),this.bindings[a]=c))}}(this),function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a){for(var b;b=a.parentNode;)a=b;return a}function d(a,b){if(b){for(var d,e="#"+b;!d&&(a=c(a),a.protoContent_?d=a.protoContent_.querySelector(e):a.getElementById&&(d=a.getElementById(b)),!d&&a.templateCreator_);)a=a.templateCreator_;return d}}function e(a){return"template"==a.tagName&&"http://www.w3.org/2000/svg"==a.namespaceURI}function f(a){return"TEMPLATE"==a.tagName&&"http://www.w3.org/1999/xhtml"==a.namespaceURI}function g(a){return Boolean(J[a.tagName]&&a.hasAttribute("template"))}function h(a){return void 0===a.isTemplate_&&(a.isTemplate_="TEMPLATE"==a.tagName||g(a)),a.isTemplate_}function i(a,b){var c=a.querySelectorAll(L);h(a)&&b(a),E(c,b)}function j(a){function b(a){HTMLTemplateElement.decorate(a)||j(a.content)}i(a,b)}function k(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))})}function l(a){var b=a.ownerDocument;if(!b.defaultView)return b;var c=b.templateContentsOwner_;if(!c){for(c=b.implementation.createHTMLDocument("");c.lastChild;)c.removeChild(c.lastChild);b.templateContentsOwner_=c}return c}function m(a){if(!a.stagingDocument_){var b=a.ownerDocument;if(!b.stagingDocument_){b.stagingDocument_=b.implementation.createHTMLDocument("");var c=b.stagingDocument_.createElement("base");c.href=document.baseURI,b.stagingDocument_.head.appendChild(c),b.stagingDocument_.stagingDocument_=b.stagingDocument_}a.stagingDocument_=b.stagingDocument_}return a.stagingDocument_}function n(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];I[e.name]&&("template"!==e.name&&b.setAttribute(e.name,e.value),a.removeAttribute(e.name))}return b}function o(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];b.setAttribute(e.name,e.value),a.removeAttribute(e.name)
-}return a.parentNode.removeChild(a),b}function p(a,b,c){var d=a.content;if(c)return void d.appendChild(b);for(var e;e=b.firstChild;)d.appendChild(e)}function q(a){N?a.__proto__=HTMLTemplateElement.prototype:k(a,HTMLTemplateElement.prototype)}function r(a){a.setModelFn_||(a.setModelFn_=function(){a.setModelFnScheduled_=!1;var b=z(a,a.delegate_&&a.delegate_.prepareBinding);w(a,b,a.model_)}),a.setModelFnScheduled_||(a.setModelFnScheduled_=!0,Observer.runEOM_(a.setModelFn_))}function s(a,b,c,d){if(a&&a.length){for(var e,f=a.length,g=0,h=0,i=0,j=!0;f>h;){var g=a.indexOf("{{",h),k=a.indexOf("[[",h),l=!1,m="}}";if(k>=0&&(0>g||g>k)&&(g=k,l=!0,m="]]"),i=0>g?-1:a.indexOf(m,g+2),0>i){if(!e)return;e.push(a.slice(h));break}e=e||[],e.push(a.slice(h,g));var n=a.slice(g+2,i).trim();e.push(l),j=j&&l,e.push(Path.get(n));var o=d&&d(n,b,c);e.push(o),h=i+2}return h===f&&e.push(""),e.hasOnePath=5===e.length,e.isSimplePath=e.hasOnePath&&""==e[0]&&""==e[4],e.onlyOneTime=j,e.combinator=function(a){for(var b=e[0],c=1;c<e.length;c+=4){var d=e.hasOnePath?a:a[(c-1)/4];void 0!==d&&(b+=d),b+=e[c+3]}return b},e}}function t(a,b,c,d){if(b.hasOnePath){var e=b[3],f=e?e(d,c,!0):b[2].getValueFrom(d);return b.isSimplePath?f:b.combinator(f)}for(var g=[],h=1;h<b.length;h+=4){var e=b[h+2];g[(h-1)/4]=e?e(d,c):b[h+1].getValueFrom(d)}return b.combinator(g)}function u(a,b,c,d){var e=b[3],f=e?e(d,c,!1):new PathObserver(d,b[2]);return b.isSimplePath?f:new ObserverTransform(f,b.combinator)}function v(a,b,c,d){if(b.onlyOneTime)return t(a,b,c,d);if(b.hasOnePath)return u(a,b,c,d);for(var e=new CompoundObserver,f=1;f<b.length;f+=4){var g=b[f],h=b[f+2];if(h){var i=h(d,c,g);g?e.addPath(i):e.addObserver(i)}else{var j=b[f+1];g?e.addPath(j.getValueFrom(d)):e.addPath(d,j)}}return new ObserverTransform(e,b.combinator)}function w(a,b,c,d){for(var e=0;e<b.length;e+=2){var f=b[e],g=b[e+1],h=v(f,g,a,c),i=a.bind(f,h,g.onlyOneTime);i&&d&&d.push(i)}if(b.isTemplate){a.model_=c;var j=a.processBindingDirectives_(b);d&&j&&d.push(j)}}function x(a,b,c){var d=a.getAttribute(b);return s(""==d?"{{}}":d,b,a,c)}function y(a,c){b(a);for(var d=[],e=0;e<a.attributes.length;e++){for(var f=a.attributes[e],g=f.name,i=f.value;"_"===g[0];)g=g.substring(1);if(!h(a)||g!==H&&g!==F&&g!==G){var j=s(i,g,a,c);j&&d.push(g,j)}}return h(a)&&(d.isTemplate=!0,d.if=x(a,H,c),d.bind=x(a,F,c),d.repeat=x(a,G,c),!d.if||d.bind||d.repeat||(d.bind=s("{{}}",F,a,c))),d}function z(a,b){if(a.nodeType===Node.ELEMENT_NODE)return y(a,b);if(a.nodeType===Node.TEXT_NODE){var c=s(a.data,"textContent",a,b);if(c)return["textContent",c]}return[]}function A(a,b,c,d,e,f,g){for(var h=b.appendChild(c.importNode(a,!1)),i=0,j=a.firstChild;j;j=j.nextSibling)A(j,h,c,d.children[i++],e,f,g);return d.isTemplate&&(HTMLTemplateElement.decorate(h,a),f&&h.setDelegate_(f)),w(h,d,e,g),h}function B(a,b){var c=z(a,b);c.children={};for(var d=0,e=a.firstChild;e;e=e.nextSibling)c.children[d++]=B(e,b);return c}function C(a){this.closed=!1,this.templateElement_=a,this.terminators=[],this.deps=void 0,this.iteratedValue=[],this.presentValue=void 0,this.arrayObserver=void 0}var D,E=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.Map&&"function"==typeof a.Map.prototype.forEach?D=a.Map:(D=function(){this.keys=[],this.values=[]},D.prototype={set:function(a,b){var c=this.keys.indexOf(a);0>c?(this.keys.push(a),this.values.push(b)):this.values[c]=b},get:function(a){var b=this.keys.indexOf(a);if(!(0>b))return this.values[b]},"delete":function(a){var b=this.keys.indexOf(a);return 0>b?!1:(this.keys.splice(b,1),this.values.splice(b,1),!0)},forEach:function(a,b){for(var c=0;c<this.keys.length;c++)a.call(b||this,this.values[c],this.keys[c],this)}});"function"!=typeof document.contains&&(Document.prototype.contains=function(a){return a===this||a.parentNode===this?!0:this.documentElement.contains(a)});var F="bind",G="repeat",H="if",I={template:!0,repeat:!0,bind:!0,ref:!0},J={THEAD:!0,TBODY:!0,TFOOT:!0,TH:!0,TR:!0,TD:!0,COLGROUP:!0,COL:!0,CAPTION:!0,OPTION:!0,OPTGROUP:!0},K="undefined"!=typeof HTMLTemplateElement;K&&!function(){var a=document.createElement("template"),b=a.content.ownerDocument,c=b.appendChild(b.createElement("html")),d=c.appendChild(b.createElement("head")),e=b.createElement("base");e.href=document.baseURI,d.appendChild(e)}();var L="template, "+Object.keys(J).map(function(a){return a.toLowerCase()+"[template]"}).join(", ");document.addEventListener("DOMContentLoaded",function(){j(document),Platform.performMicrotaskCheckpoint()},!1),K||(a.HTMLTemplateElement=function(){throw TypeError("Illegal constructor")});var M,N="__proto__"in{};"function"==typeof MutationObserver&&(M=new MutationObserver(function(a){for(var b=0;b<a.length;b++)a[b].target.refChanged_()})),HTMLTemplateElement.decorate=function(a,c){if(a.templateIsDecorated_)return!1;var d=a;d.templateIsDecorated_=!0;var h=f(d)&&K,i=h,k=!h,m=!1;if(h||(g(d)?(b(!c),d=n(a),d.templateIsDecorated_=!0,h=K,m=!0):e(d)&&(d=o(a),d.templateIsDecorated_=!0,h=K)),!h){q(d);var r=l(d);d.content_=r.createDocumentFragment()}return c?d.instanceRef_=c:k?p(d,a,m):i&&j(d.content),!0},HTMLTemplateElement.bootstrap=j;var O=a.HTMLUnknownElement||HTMLElement,P={get:function(){return this.content_},enumerable:!0,configurable:!0};K||(HTMLTemplateElement.prototype=Object.create(O.prototype),Object.defineProperty(HTMLTemplateElement.prototype,"content",P)),k(HTMLTemplateElement.prototype,{bind:function(a,b,c){if("ref"!=a)return Element.prototype.bind.call(this,a,b,c);var d=this,e=c?b:b.open(function(a){d.setAttribute("ref",a),d.refChanged_()});return this.setAttribute("ref",e),this.refChanged_(),c?void 0:(this.unbind("ref"),this.bindings.ref=b)},processBindingDirectives_:function(a){return this.iterator_&&this.iterator_.closeDeps(),a.if||a.bind||a.repeat?(this.iterator_||(this.iterator_=new C(this),this.bindings=this.bindings||{},this.bindings.iterator=this.iterator_),this.iterator_.updateDependencies(a,this.model_),M&&M.observe(this,{attributes:!0,attributeFilter:["ref"]}),this.iterator_):void(this.iterator_&&(this.iterator_.close(),this.iterator_=void 0,this.bindings.iterator=void 0))},createInstance:function(a,b,c,d){b&&(c=this.newDelegate_(b)),this.refContent_||(this.refContent_=this.ref_.content);var e=this.refContent_,f=this.bindingMap_;f&&f.content===e||(f=B(e,c&&c.prepareBinding)||[],f.content=e,this.bindingMap_=f);var g=m(this),h=g.createDocumentFragment();h.templateCreator_=this,h.protoContent_=e;for(var i={firstNode:null,lastNode:null,model:a},j=0,k=e.firstChild;k;k=k.nextSibling){var l=A(k,h,g,f.children[j++],a,c,d);l.templateInstance_=i}return i.firstNode=h.firstChild,i.lastNode=h.lastChild,h.templateCreator_=void 0,h.protoContent_=void 0,h},get model(){return this.model_},set model(a){this.model_=a,r(this)},get bindingDelegate(){return this.delegate_&&this.delegate_.raw},refChanged_:function(){this.iterator_&&this.refContent_!==this.ref_.content&&(this.refContent_=void 0,this.iterator_.valueChanged(),this.iterator_.updateIteratedValue())},clear:function(){this.model_=void 0,this.delegate_=void 0,this.bindings_=void 0,this.refContent_=void 0,this.iterator_&&(this.iterator_.valueChanged(),this.iterator_.close(),this.iterator_=void 0)},setDelegate_:function(a){this.delegate_=a,this.bindingMap_=void 0,this.iterator_&&(this.iterator_.instancePositionChangedFn_=void 0,this.iterator_.instanceModelFn_=void 0)},newDelegate_:function(a){function b(b){var c=a&&a[b];if("function"==typeof c)return function(){return c.apply(a,arguments)}}return a?{raw:a,prepareBinding:b("prepareBinding"),prepareInstanceModel:b("prepareInstanceModel"),prepareInstancePositionChanged:b("prepareInstancePositionChanged")}:{}},set bindingDelegate(a){if(this.delegate_)throw Error("Template must be cleared before a new bindingDelegate can be assigned");this.setDelegate_(this.newDelegate_(a))},get ref_(){var a=d(this,this.getAttribute("ref"));if(a||(a=this.instanceRef_),!a)return this;var b=a.ref_;return b?b:a}}),Object.defineProperty(Node.prototype,"templateInstance",{get:function(){var a=this.templateInstance_;return a?a:this.parentNode?this.parentNode.templateInstance:void 0}}),C.prototype={closeDeps:function(){var a=this.deps;a&&(a.ifOneTime===!1&&a.ifValue.close(),a.oneTime===!1&&a.value.close())},updateDependencies:function(a,b){this.closeDeps();var c=this.deps={},d=this.templateElement_;if(a.if){if(c.hasIf=!0,c.ifOneTime=a.if.onlyOneTime,c.ifValue=v(H,a.if,d,b),c.ifOneTime&&!c.ifValue)return void this.updateIteratedValue();c.ifOneTime||c.ifValue.open(this.updateIteratedValue,this)}a.repeat?(c.repeat=!0,c.oneTime=a.repeat.onlyOneTime,c.value=v(G,a.repeat,d,b)):(c.repeat=!1,c.oneTime=a.bind.onlyOneTime,c.value=v(F,a.bind,d,b)),c.oneTime||c.value.open(this.updateIteratedValue,this),this.updateIteratedValue()},updateIteratedValue:function(){if(this.deps.hasIf){var a=this.deps.ifValue;if(this.deps.ifOneTime||(a=a.discardChanges()),!a)return void this.valueChanged()}var b=this.deps.value;this.deps.oneTime||(b=b.discardChanges()),this.deps.repeat||(b=[b]);var c=this.deps.repeat&&!this.deps.oneTime&&Array.isArray(b);this.valueChanged(b,c)},valueChanged:function(a,b){Array.isArray(a)||(a=[]),a!==this.iteratedValue&&(this.unobserve(),this.presentValue=a,b&&(this.arrayObserver=new ArrayObserver(this.presentValue),this.arrayObserver.open(this.handleSplices,this)),this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,this.iteratedValue)))},getTerminatorAt:function(a){if(-1==a)return this.templateElement_;var b=this.terminators[2*a];if(b.nodeType!==Node.ELEMENT_NODE||this.templateElement_===b)return b;var c=b.iterator_;return c?c.getTerminatorAt(c.terminators.length/2-1):b},insertInstanceAt:function(a,b,c,d){var e=this.getTerminatorAt(a-1),f=e;b?f=b.lastChild||f:c&&(f=c[c.length-1]||f),this.terminators.splice(2*a,0,f,d);var g=this.templateElement_.parentNode,h=e.nextSibling;if(b)g.insertBefore(b,h);else if(c)for(var i=0;i<c.length;i++)g.insertBefore(c[i],h)},extractInstanceAt:function(a){var b=[],c=this.getTerminatorAt(a-1),d=this.getTerminatorAt(a);b.instanceBindings=this.terminators[2*a+1],this.terminators.splice(2*a,2);for(var e=this.templateElement_.parentNode;d!==c;){var f=c.nextSibling;f==d&&(d=c),e.removeChild(f),b.push(f)}return b},getDelegateFn:function(a){return a=a&&a(this.templateElement_),"function"==typeof a?a:null},handleSplices:function(a){if(!this.closed&&a.length){var b=this.templateElement_;if(!b.parentNode)return void this.close();ArrayObserver.applySplices(this.iteratedValue,this.presentValue,a);var c=b.delegate_;void 0===this.instanceModelFn_&&(this.instanceModelFn_=this.getDelegateFn(c&&c.prepareInstanceModel)),void 0===this.instancePositionChangedFn_&&(this.instancePositionChangedFn_=this.getDelegateFn(c&&c.prepareInstancePositionChanged));var d=new D,e=0;a.forEach(function(a){a.removed.forEach(function(b){var c=this.extractInstanceAt(a.index+e);d.set(b,c)},this),e-=a.addedCount},this),a.forEach(function(a){for(var e=a.index;e<a.index+a.addedCount;e++){var f,g=this.iteratedValue[e],h=void 0,i=d.get(g);i?(d.delete(g),f=i.instanceBindings):(f=[],this.instanceModelFn_&&(g=this.instanceModelFn_(g)),void 0!==g&&(h=b.createInstance(g,void 0,c,f))),this.insertInstanceAt(e,h,i,f)}},this),d.forEach(function(a){this.closeInstanceBindings(a.instanceBindings)},this),this.instancePositionChangedFn_&&this.reportInstancesMoved(a)}},reportInstanceMoved:function(a){var b=this.getTerminatorAt(a-1),c=this.getTerminatorAt(a);if(b!==c){var d=b.nextSibling.templateInstance;this.instancePositionChangedFn_(d,a)}},reportInstancesMoved:function(a){for(var b=0,c=0,d=0;d<a.length;d++){var e=a[d];if(0!=c)for(;b<e.index;)this.reportInstanceMoved(b),b++;else b=e.index;for(;b<e.index+e.addedCount;)this.reportInstanceMoved(b),b++;c+=e.addedCount-e.removed.length}if(0!=c)for(var f=this.terminators.length/2;f>b;)this.reportInstanceMoved(b),b++},closeInstanceBindings:function(a){for(var b=0;b<a.length;b++)a[b].close()},unobserve:function(){this.arrayObserver&&(this.arrayObserver.close(),this.arrayObserver=void 0)},close:function(){if(!this.closed){this.unobserve();for(var a=1;a<this.terminators.length;a+=2)this.closeInstanceBindings(this.terminators[a]);this.terminators.length=0,this.closeDeps(),this.templateElement_.iterator_=void 0,this.closed=!0}}},HTMLTemplateElement.forAllTemplatesFrom_=i}(this),function(a){"use strict";function b(a,b){if(!a)throw new Error("ASSERT: "+b)}function c(a){return a>=48&&57>=a}function d(a){return 32===a||9===a||11===a||12===a||160===a||a>=5760&&" ᠎              ".indexOf(String.fromCharCode(a))>0}function e(a){return 10===a||13===a||8232===a||8233===a}function f(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a}function g(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a||a>=48&&57>=a}function h(a){return"this"===a}function i(){for(;Y>X&&d(W.charCodeAt(X));)++X}function j(){var a,b;for(a=X++;Y>X&&(b=W.charCodeAt(X),g(b));)++X;return W.slice(a,X)}function k(){var a,b,c;return a=X,b=j(),c=1===b.length?S.Identifier:h(b)?S.Keyword:"null"===b?S.NullLiteral:"true"===b||"false"===b?S.BooleanLiteral:S.Identifier,{type:c,value:b,range:[a,X]}}function l(){var a,b,c=X,d=W.charCodeAt(X),e=W[X];switch(d){case 46:case 40:case 41:case 59:case 44:case 123:case 125:case 91:case 93:case 58:case 63:return++X,{type:S.Punctuator,value:String.fromCharCode(d),range:[c,X]};default:if(a=W.charCodeAt(X+1),61===a)switch(d){case 37:case 38:case 42:case 43:case 45:case 47:case 60:case 62:case 124:return X+=2,{type:S.Punctuator,value:String.fromCharCode(d)+String.fromCharCode(a),range:[c,X]};case 33:case 61:return X+=2,61===W.charCodeAt(X)&&++X,{type:S.Punctuator,value:W.slice(c,X),range:[c,X]}}}return b=W[X+1],e===b&&"&|".indexOf(e)>=0?(X+=2,{type:S.Punctuator,value:e+b,range:[c,X]}):"<>=!+-*%&|^/".indexOf(e)>=0?(++X,{type:S.Punctuator,value:e,range:[c,X]}):void s({},V.UnexpectedToken,"ILLEGAL")}function m(){var a,d,e;if(e=W[X],b(c(e.charCodeAt(0))||"."===e,"Numeric literal must start with a decimal digit or a decimal point"),d=X,a="","."!==e){for(a=W[X++],e=W[X],"0"===a&&e&&c(e.charCodeAt(0))&&s({},V.UnexpectedToken,"ILLEGAL");c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("."===e){for(a+=W[X++];c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("e"===e||"E"===e)if(a+=W[X++],e=W[X],("+"===e||"-"===e)&&(a+=W[X++]),c(W.charCodeAt(X)))for(;c(W.charCodeAt(X));)a+=W[X++];else s({},V.UnexpectedToken,"ILLEGAL");return f(W.charCodeAt(X))&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.NumericLiteral,value:parseFloat(a),range:[d,X]}}function n(){var a,c,d,f="",g=!1;for(a=W[X],b("'"===a||'"'===a,"String literal must starts with a quote"),c=X,++X;Y>X;){if(d=W[X++],d===a){a="";break}if("\\"===d)if(d=W[X++],d&&e(d.charCodeAt(0)))"\r"===d&&"\n"===W[X]&&++X;else switch(d){case"n":f+="\n";break;case"r":f+="\r";break;case"t":f+="	";break;case"b":f+="\b";break;case"f":f+="\f";break;case"v":f+="";break;default:f+=d}else{if(e(d.charCodeAt(0)))break;f+=d}}return""!==a&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.StringLiteral,value:f,octal:g,range:[c,X]}}function o(a){return a.type===S.Identifier||a.type===S.Keyword||a.type===S.BooleanLiteral||a.type===S.NullLiteral}function p(){var a;return i(),X>=Y?{type:S.EOF,range:[X,X]}:(a=W.charCodeAt(X),40===a||41===a||58===a?l():39===a||34===a?n():f(a)?k():46===a?c(W.charCodeAt(X+1))?m():l():c(a)?m():l())}function q(){var a;return a=$,X=a.range[1],$=p(),X=a.range[1],a}function r(){var a;a=X,$=p(),X=a}function s(a,c){var d,e=Array.prototype.slice.call(arguments,2),f=c.replace(/%(\d)/g,function(a,c){return b(c<e.length,"Message reference must be in range"),e[c]});throw d=new Error(f),d.index=X,d.description=f,d}function t(a){s(a,V.UnexpectedToken,a.value)}function u(a){var b=q();(b.type!==S.Punctuator||b.value!==a)&&t(b)}function v(a){return $.type===S.Punctuator&&$.value===a}function w(a){return $.type===S.Keyword&&$.value===a}function x(){var a=[];for(u("[");!v("]");)v(",")?(q(),a.push(null)):(a.push(bb()),v("]")||u(","));return u("]"),Z.createArrayExpression(a)}function y(){var a;return i(),a=q(),a.type===S.StringLiteral||a.type===S.NumericLiteral?Z.createLiteral(a):Z.createIdentifier(a.value)}function z(){var a,b;return a=$,i(),(a.type===S.EOF||a.type===S.Punctuator)&&t(a),b=y(),u(":"),Z.createProperty("init",b,bb())}function A(){var a=[];for(u("{");!v("}");)a.push(z()),v("}")||u(",");return u("}"),Z.createObjectExpression(a)}function B(){var a;return u("("),a=bb(),u(")"),a}function C(){var a,b,c;return v("(")?B():(a=$.type,a===S.Identifier?c=Z.createIdentifier(q().value):a===S.StringLiteral||a===S.NumericLiteral?c=Z.createLiteral(q()):a===S.Keyword?w("this")&&(q(),c=Z.createThisExpression()):a===S.BooleanLiteral?(b=q(),b.value="true"===b.value,c=Z.createLiteral(b)):a===S.NullLiteral?(b=q(),b.value=null,c=Z.createLiteral(b)):v("[")?c=x():v("{")&&(c=A()),c?c:void t(q()))}function D(){var a=[];if(u("("),!v(")"))for(;Y>X&&(a.push(bb()),!v(")"));)u(",");return u(")"),a}function E(){var a;return a=q(),o(a)||t(a),Z.createIdentifier(a.value)}function F(){return u("."),E()}function G(){var a;return u("["),a=bb(),u("]"),a}function H(){var a,b;for(a=C();v(".")||v("[");)v("[")?(b=G(),a=Z.createMemberExpression("[",a,b)):(b=F(),a=Z.createMemberExpression(".",a,b));return a}function I(){var a,b;return $.type!==S.Punctuator&&$.type!==S.Keyword?b=ab():v("+")||v("-")||v("!")?(a=q(),b=I(),b=Z.createUnaryExpression(a.value,b)):w("delete")||w("void")||w("typeof")?s({},V.UnexpectedToken):b=ab(),b}function J(a){var b=0;if(a.type!==S.Punctuator&&a.type!==S.Keyword)return 0;switch(a.value){case"||":b=1;break;case"&&":b=2;break;case"==":case"!=":case"===":case"!==":b=6;break;case"<":case">":case"<=":case">=":case"instanceof":b=7;break;case"in":b=7;break;case"+":case"-":b=9;break;case"*":case"/":case"%":b=11}return b}function K(){var a,b,c,d,e,f,g,h;if(g=I(),b=$,c=J(b),0===c)return g;for(b.prec=c,q(),e=I(),d=[g,b,e];(c=J($))>0;){for(;d.length>2&&c<=d[d.length-2].prec;)e=d.pop(),f=d.pop().value,g=d.pop(),a=Z.createBinaryExpression(f,g,e),d.push(a);b=q(),b.prec=c,d.push(b),a=I(),d.push(a)}for(h=d.length-1,a=d[h];h>1;)a=Z.createBinaryExpression(d[h-1].value,d[h-2],a),h-=2;return a}function L(){var a,b,c;return a=K(),v("?")&&(q(),b=L(),u(":"),c=L(),a=Z.createConditionalExpression(a,b,c)),a}function M(){var a,b;return a=q(),a.type!==S.Identifier&&t(a),b=v("(")?D():[],Z.createFilter(a.value,b)}function N(){for(;v("|");)q(),M()}function O(){i(),r();var a=bb();a&&(","===$.value||"in"==$.value&&a.type===U.Identifier?Q(a):(N(),"as"===$.value?P(a):Z.createTopLevel(a))),$.type!==S.EOF&&t($)}function P(a){q();var b=q().value;Z.createAsExpression(a,b)}function Q(a){var b;","===$.value&&(q(),$.type!==S.Identifier&&t($),b=q().value),q();var c=bb();N(),Z.createInExpression(a.name,b,c)}function R(a,b){return Z=b,W=a,X=0,Y=W.length,$=null,_={labelSet:{}},O()}var S,T,U,V,W,X,Y,Z,$,_;S={BooleanLiteral:1,EOF:2,Identifier:3,Keyword:4,NullLiteral:5,NumericLiteral:6,Punctuator:7,StringLiteral:8},T={},T[S.BooleanLiteral]="Boolean",T[S.EOF]="<end>",T[S.Identifier]="Identifier",T[S.Keyword]="Keyword",T[S.NullLiteral]="Null",T[S.NumericLiteral]="Numeric",T[S.Punctuator]="Punctuator",T[S.StringLiteral]="String",U={ArrayExpression:"ArrayExpression",BinaryExpression:"BinaryExpression",CallExpression:"CallExpression",ConditionalExpression:"ConditionalExpression",EmptyStatement:"EmptyStatement",ExpressionStatement:"ExpressionStatement",Identifier:"Identifier",Literal:"Literal",LabeledStatement:"LabeledStatement",LogicalExpression:"LogicalExpression",MemberExpression:"MemberExpression",ObjectExpression:"ObjectExpression",Program:"Program",Property:"Property",ThisExpression:"ThisExpression",UnaryExpression:"UnaryExpression"},V={UnexpectedToken:"Unexpected token %0",UnknownLabel:"Undefined label '%0'",Redeclaration:"%0 '%1' has already been declared"};var ab=H,bb=L;a.esprima={parse:R}}(this),function(a){"use strict";function b(a,b,d,e){var f;try{if(f=c(a),f.scopeIdent&&(d.nodeType!==Node.ELEMENT_NODE||"TEMPLATE"!==d.tagName||"bind"!==b&&"repeat"!==b))throw Error("as and in can only be used within <template bind/repeat>")}catch(g){return void console.error("Invalid expression syntax: "+a,g)}return function(a,b,c){var d=f.getBinding(a,e,c);return f.scopeIdent&&d&&(b.polymerExpressionScopeIdent_=f.scopeIdent,f.indexIdent&&(b.polymerExpressionIndexIdent_=f.indexIdent)),d}}function c(a){var b=s[a];if(!b){var c=new j;esprima.parse(a,c),b=new l(c),s[a]=b}return b}function d(a){this.value=a,this.valueFn_=void 0}function e(a){this.name=a,this.path=Path.get(a)}function f(a,b,c){"["==c&&b instanceof d&&Path.get(b.value).valid&&(c=".",b=new e(b.value)),this.dynamicDeps="function"==typeof a||a.dynamic,this.dynamic="function"==typeof b||b.dynamic||"["==c,this.simplePath=!this.dynamic&&!this.dynamicDeps&&b instanceof e&&(a instanceof f||a instanceof e),this.object=this.simplePath?a:i(a),this.property="."==c?b:i(b)}function g(a,b){this.name=a,this.args=[];for(var c=0;c<b.length;c++)this.args[c]=i(b[c])}function h(){throw Error("Not Implemented")}function i(a){return"function"==typeof a?a:a.valueFn()}function j(){this.expression=null,this.filters=[],this.deps={},this.currentPath=void 0,this.scopeIdent=void 0,this.indexIdent=void 0,this.dynamicDeps=!1}function k(a){this.value_=a}function l(a){if(this.scopeIdent=a.scopeIdent,this.indexIdent=a.indexIdent,!a.expression)throw Error("No expression found.");this.expression=a.expression,i(this.expression),this.filters=a.filters,this.dynamicDeps=a.dynamicDeps}function m(a){return String(a).replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function n(a){return"o"===a[0]&&"n"===a[1]&&"-"===a[2]}function o(a,b){for(;a[w]&&!Object.prototype.hasOwnProperty.call(a,b);)a=a[w];return a}function p(a,b){if(0==b.length)return void 0;if(1==b.length)return o(a,b[0]);for(var c=0;null!=a&&c<b.length-1;c++)a=a[b[c]];return a}function q(a,b,c){var d=b.substring(3);return d=v[d]||d,function(b,e,f){function g(){return"{{ "+a+" }}"}var h,i,j;return j="function"==typeof c.resolveEventHandler?function(d){h=h||c.resolveEventHandler(b,a,e),h(d,d.detail,d.currentTarget),Platform&&"function"==typeof Platform.flush&&Platform.flush()}:function(c){h=h||a.getValueFrom(b),i=i||p(b,a,e),h.apply(i,[c,c.detail,c.currentTarget]),Platform&&"function"==typeof Platform.flush&&Platform.flush()},e.addEventListener(d,j),f?void 0:{open:g,discardChanges:g,close:function(){e.removeEventListener(d,j)}}}}function r(){}var s=Object.create(null);d.prototype={valueFn:function(){if(!this.valueFn_){var a=this.value;this.valueFn_=function(){return a}}return this.valueFn_}},e.prototype={valueFn:function(){if(!this.valueFn_){var a=(this.name,this.path);this.valueFn_=function(b,c){return c&&c.addPath(b,a),a.getValueFrom(b)}}return this.valueFn_},setValue:function(a,b){return 1==this.path.length,a=o(a,this.path[0]),this.path.setValueFrom(a,b)}},f.prototype={get fullPath(){if(!this.fullPath_){var a=this.object instanceof e?this.object.name:this.object.fullPath;this.fullPath_=Path.get(a+"."+this.property.name)}return this.fullPath_},valueFn:function(){if(!this.valueFn_){var a=this.object;if(this.simplePath){var b=this.fullPath;this.valueFn_=function(a,c){return c&&c.addPath(a,b),b.getValueFrom(a)}}else if(this.property instanceof e){var b=Path.get(this.property.name);this.valueFn_=function(c,d){var e=a(c,d);return d&&d.addPath(e,b),b.getValueFrom(e)}}else{var c=this.property;this.valueFn_=function(b,d){var e=a(b,d),f=c(b,d);return d&&d.addPath(e,f),e?e[f]:void 0}}}return this.valueFn_},setValue:function(a,b){if(this.simplePath)return this.fullPath.setValueFrom(a,b),b;var c=this.object(a),d=this.property instanceof e?this.property.name:this.property(a);return c[d]=b}},g.prototype={transform:function(a,b,c,d,e){var f=c[this.name],g=d;if(f)g=void 0;else if(f=g[this.name],!f)return void console.error("Cannot find filter: "+this.name);if(b?f=f.toModel:"function"==typeof f.toDOM&&(f=f.toDOM),"function"!=typeof f)return void console.error("No "+(b?"toModel":"toDOM")+" found on"+this.name);for(var h=[a],j=0;j<this.args.length;j++)h[j+1]=i(this.args[j])(d,e);return f.apply(g,h)}};var t={"+":function(a){return+a},"-":function(a){return-a},"!":function(a){return!a}},u={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"*":function(a,b){return a*b},"/":function(a,b){return a/b},"%":function(a,b){return a%b},"<":function(a,b){return b>a},">":function(a,b){return a>b},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"==":function(a,b){return a==b},"!=":function(a,b){return a!=b},"===":function(a,b){return a===b},"!==":function(a,b){return a!==b},"&&":function(a,b){return a&&b},"||":function(a,b){return a||b}};j.prototype={createUnaryExpression:function(a,b){if(!t[a])throw Error("Disallowed operator: "+a);return b=i(b),function(c,d){return t[a](b(c,d))}},createBinaryExpression:function(a,b,c){if(!u[a])throw Error("Disallowed operator: "+a);return b=i(b),c=i(c),function(d,e){return u[a](b(d,e),c(d,e))}},createConditionalExpression:function(a,b,c){return a=i(a),b=i(b),c=i(c),function(d,e){return a(d,e)?b(d,e):c(d,e)}},createIdentifier:function(a){var b=new e(a);return b.type="Identifier",b},createMemberExpression:function(a,b,c){var d=new f(b,c,a);return d.dynamicDeps&&(this.dynamicDeps=!0),d},createLiteral:function(a){return new d(a.value)},createArrayExpression:function(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return function(b,c){for(var d=[],e=0;e<a.length;e++)d.push(a[e](b,c));return d}},createProperty:function(a,b,c){return{key:b instanceof e?b.name:b.value,value:c}},createObjectExpression:function(a){for(var b=0;b<a.length;b++)a[b].value=i(a[b].value);return function(b,c){for(var d={},e=0;e<a.length;e++)d[a[e].key]=a[e].value(b,c);return d}},createFilter:function(a,b){this.filters.push(new g(a,b))},createAsExpression:function(a,b){this.expression=a,this.scopeIdent=b},createInExpression:function(a,b,c){this.expression=c,this.scopeIdent=a,this.indexIdent=b},createTopLevel:function(a){this.expression=a},createThisExpression:h},k.prototype={open:function(){return this.value_},discardChanges:function(){return this.value_},deliver:function(){},close:function(){}},l.prototype={getBinding:function(a,b,c){function d(){g.dynamicDeps&&f.startReset();var c=g.getValue(a,g.dynamicDeps?f:void 0,b);return g.dynamicDeps&&f.finishReset(),c}function e(c){return g.setValue(a,c,b),c}if(c)return this.getValue(a,void 0,b);var f=new CompoundObserver;this.getValue(a,f,b);var g=this;return new ObserverTransform(f,d,e,!0)},getValue:function(a,b,c){for(var d=i(this.expression)(a,b),e=0;e<this.filters.length;e++)d=this.filters[e].transform(d,!1,c,a,b);return d},setValue:function(a,b,c){for(var d=this.filters?this.filters.length:0;d-->0;)b=this.filters[d].transform(b,!0,c,a);return this.expression.setValue?this.expression.setValue(a,b):void 0}};var v={};["webkitAnimationStart","webkitAnimationEnd","webkitTransitionEnd","DOMFocusOut","DOMFocusIn","DOMMouseScroll"].forEach(function(a){v[a.toLowerCase()]=a});var w="@"+Math.random().toString(36).slice(2);r.prototype={styleObject:function(a){var b=[];for(var c in a)b.push(m(c)+": "+a[c]);return b.join("; ")},tokenList:function(a){var b=[];for(var c in a)a[c]&&b.push(c);return b.join(" ")},prepareInstancePositionChanged:function(a){var b=a.polymerExpressionIndexIdent_;if(b)return function(a,c){a.model[b]=c}},prepareBinding:function(a,c,d){var e=Path.get(a);if(n(c))return e.valid?q(e,c,this):void console.error("on-* bindings must be simple path expressions");{if(!e.valid)return b(a,c,d,this);if(1==e.length)return function(a,b,c){if(c)return e.getValueFrom(a);var d=o(a,e[0]);return new PathObserver(d,e)}}},prepareInstanceModel:function(a){var b=a.polymerExpressionScopeIdent_;if(b){var c=a.templateInstance?a.templateInstance.model:a.model,d=a.polymerExpressionIndexIdent_;return function(a){var e=Object.create(c);return e[b]=a,e[d]=void 0,e[w]=c,e}}}},a.PolymerExpressions=r,a.exposeGetExpression&&(a.getExpression_=c),a.PolymerExpressions.prepareEventBinding=q}(this),function(a){function b(){e||(e=!0,a.endOfMicrotask(function(){e=!1,logFlags.data&&console.group("Platform.flush()"),a.performMicrotaskCheckpoint(),logFlags.data&&console.groupEnd()}))}var c=document.createElement("style");c.textContent="template {display: none !important;} /* injected by platform.js */";var d=document.querySelector("head");d.insertBefore(c,d.firstChild);var e,f=125;if(window.addEventListener("WebComponentsReady",function(){b(),Observer.hasObjectObserve||(a.flushPoll=setInterval(b,f))}),window.CustomElements&&!CustomElements.useNative){var g=Document.prototype.importNode;Document.prototype.importNode=function(a,b){var c=g.call(this,a,b);return CustomElements.upgradeAll(c),c}}a.flush=b}(window.Platform);
-//# sourceMappingURL=platform.js.map
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js.map b/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js.map
deleted file mode 100644
index 2a16da5..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"platform.js","sources":["../PointerGestures/src/PointerGestureEvent.js","../WeakMap/weakmap.js","../observe-js/src/observe.js","build/if-poly.js","../ShadowDOM/src/wrappers.js","../ShadowDOM/src/microtask.js","../ShadowDOM/src/MutationObserver.js","../ShadowDOM/src/TreeScope.js","../ShadowDOM/src/wrappers/events.js","../ShadowDOM/src/wrappers/NodeList.js","../ShadowDOM/src/wrappers/HTMLCollection.js","../ShadowDOM/src/wrappers/Node.js","../ShadowDOM/src/querySelector.js","../ShadowDOM/src/wrappers/node-interfaces.js","../ShadowDOM/src/wrappers/CharacterData.js","../ShadowDOM/src/wrappers/Text.js","../ShadowDOM/src/wrappers/Element.js","../ShadowDOM/src/wrappers/HTMLElement.js","../ShadowDOM/src/wrappers/HTMLCanvasElement.js","../ShadowDOM/src/wrappers/HTMLContentElement.js","../ShadowDOM/src/wrappers/HTMLImageElement.js","../ShadowDOM/src/wrappers/HTMLShadowElement.js","../ShadowDOM/src/wrappers/HTMLTemplateElement.js","../ShadowDOM/src/wrappers/HTMLMediaElement.js","../ShadowDOM/src/wrappers/HTMLAudioElement.js","../ShadowDOM/src/wrappers/HTMLOptionElement.js","../ShadowDOM/src/wrappers/HTMLSelectElement.js","../ShadowDOM/src/wrappers/HTMLTableElement.js","../ShadowDOM/src/wrappers/HTMLTableSectionElement.js","../ShadowDOM/src/wrappers/HTMLTableRowElement.js","../ShadowDOM/src/wrappers/HTMLUnknownElement.js","../ShadowDOM/src/wrappers/SVGElement.js","../ShadowDOM/src/wrappers/SVGUseElement.js","../ShadowDOM/src/wrappers/SVGElementInstance.js","../ShadowDOM/src/wrappers/CanvasRenderingContext2D.js","../ShadowDOM/src/wrappers/WebGLRenderingContext.js","../ShadowDOM/src/wrappers/Range.js","../ShadowDOM/src/wrappers/generic.js","../ShadowDOM/src/wrappers/ShadowRoot.js","../ShadowDOM/src/ShadowRenderer.js","../ShadowDOM/src/wrappers/elements-with-form-property.js","../ShadowDOM/src/wrappers/Selection.js","../ShadowDOM/src/wrappers/Document.js","../ShadowDOM/src/wrappers/Window.js","../ShadowDOM/src/wrappers/DataTransfer.js","../ShadowDOM/src/wrappers/override-constructors.js","src/patches-shadowdom-polyfill.js","src/ShadowCSS.js","src/patches-shadowdom-native.js","../URL/url.js","src/lang.js","src/dom.js","src/template.js","src/inspector.js","src/unresolved.js","src/module.js","src/microtask.js","src/url.js","../MutationObservers/MutationObserver.js","../HTMLImports/src/scope.js","../HTMLImports/src/Loader.js","../HTMLImports/src/Parser.js","../HTMLImports/src/HTMLImports.js","../HTMLImports/src/Observer.js","../HTMLImports/src/boot.js","../CustomElements/src/scope.js","../CustomElements/src/Observer.js","../CustomElements/src/CustomElements.js","../CustomElements/src/Parser.js","../CustomElements/src/boot.js","src/patches-custom-elements.js","src/loader.js","src/styleloader.js","../PointerEvents/src/boot.js","../PointerEvents/src/touch-action.js","../PointerEvents/src/PointerEvent.js","../PointerEvents/src/pointermap.js","../PointerEvents/src/dispatcher.js","../PointerEvents/src/installer.js","../PointerEvents/src/mouse.js","../PointerEvents/src/touch.js","../PointerEvents/src/ms.js","../PointerEvents/src/platform-events.js","../PointerEvents/src/capture.js","../PointerGestures/src/initialize.js","../PointerGestures/src/pointermap.js","../PointerGestures/src/dispatcher.js","../PointerGestures/src/hold.js","../PointerGestures/src/track.js","../PointerGestures/src/flick.js","../PointerGestures/src/pinch.js","../PointerGestures/src/tap.js","../PointerGestures/src/registerScopes.js","../NodeBind/src/NodeBind.js","../TemplateBinding/src/TemplateBinding.js","../polymer-expressions/third_party/esprima/esprima.js","../polymer-expressions/src/polymer-expressions.js","src/patches-mdv.js"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * PointerGestureEvent is the constructor for all PointerGesture events.\n *\n * @module PointerGestures\n * @class PointerGestureEvent\n * @extends UIEvent\n * @constructor\n * @param {String} inType Event type\n * @param {Object} [inDict] Dictionary of properties to initialize on the event\n */\n\nfunction PointerGestureEvent(inType, inDict) {\n  var dict = inDict || {};\n  var e = document.createEvent('Event');\n  var props = {\n    bubbles: Boolean(dict.bubbles) === dict.bubbles || true,\n    cancelable: Boolean(dict.cancelable) === dict.cancelable || true\n  };\n\n  e.initEvent(inType, props.bubbles, props.cancelable);\n\n  var keys = Object.keys(dict), k;\n  for (var i = 0; i < keys.length; i++) {\n    k = keys[i];\n    e[k] = dict[k];\n  }\n\n  e.preventTap = this.preventTap;\n\n  return e;\n}\n\n/**\n * Allows for any gesture to prevent the tap gesture.\n *\n * @method preventTap\n */\nPointerGestureEvent.prototype.preventTap = function() {\n  this.tapPrevented = true;\n};\n\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nif (typeof WeakMap === 'undefined') {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n\n    var WeakMap = function() {\n      this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');\n    };\n\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key)\n          entry[1] = value;\n        else\n          defineProperty(key, this.name, {value: [key, value], writable: true});\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ?\n            entry[1] : undefined;\n      },\n      delete: function(key) {\n        this.set(key, undefined);\n      }\n    };\n\n    window.WeakMap = WeakMap;\n  })();\n}\n","// Copyright 2012 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(global) {\n  'use strict';\n\n  var PROP_ADD_TYPE = 'add';\n  var PROP_UPDATE_TYPE = 'update';\n  var PROP_RECONFIGURE_TYPE = 'reconfigure';\n  var PROP_DELETE_TYPE = 'delete';\n  var ARRAY_SPLICE_TYPE = 'splice';\n\n  // Detect and do basic sanity checking on Object/Array.observe.\n  function detectObjectObserve() {\n    if (typeof Object.observe !== 'function' ||\n        typeof Array.observe !== 'function') {\n      return false;\n    }\n\n    var records = [];\n\n    function callback(recs) {\n      records = recs;\n    }\n\n    var test = {};\n    Object.observe(test, callback);\n    test.id = 1;\n    test.id = 2;\n    delete test.id;\n    Object.deliverChangeRecords(callback);\n    if (records.length !== 3)\n      return false;\n\n    // TODO(rafaelw): Remove this when new change record type names make it to\n    // chrome release.\n    if (records[0].type == 'new' &&\n        records[1].type == 'updated' &&\n        records[2].type == 'deleted') {\n      PROP_ADD_TYPE = 'new';\n      PROP_UPDATE_TYPE = 'updated';\n      PROP_RECONFIGURE_TYPE = 'reconfigured';\n      PROP_DELETE_TYPE = 'deleted';\n    } else if (records[0].type != 'add' ||\n               records[1].type != 'update' ||\n               records[2].type != 'delete') {\n      console.error('Unexpected change record names for Object.observe. ' +\n                    'Using dirty-checking instead');\n      return false;\n    }\n    Object.unobserve(test, callback);\n\n    test = [0];\n    Array.observe(test, callback);\n    test[1] = 1;\n    test.length = 0;\n    Object.deliverChangeRecords(callback);\n    if (records.length != 2)\n      return false;\n    if (records[0].type != ARRAY_SPLICE_TYPE ||\n        records[1].type != ARRAY_SPLICE_TYPE) {\n      return false;\n    }\n    Array.unobserve(test, callback);\n\n    return true;\n  }\n\n  var hasObserve = detectObjectObserve();\n\n  function detectEval() {\n    // don't test for eval if document has CSP securityPolicy object and we can see that\n    // eval is not supported. This avoids an error message in console even when the exception\n    // is caught\n    if (global.document &&\n        'securityPolicy' in global.document &&\n        !global.document.securityPolicy.allowsEval) {\n      return false;\n    }\n\n    try {\n      var f = new Function('', 'return true;');\n      return f();\n    } catch (ex) {\n      return false;\n    }\n  }\n\n  var hasEval = detectEval();\n\n  function isIndex(s) {\n    return +s === s >>> 0;\n  }\n\n  function toNumber(s) {\n    return +s;\n  }\n\n  function isObject(obj) {\n    return obj === Object(obj);\n  }\n\n  var numberIsNaN = global.Number.isNaN || function isNaN(value) {\n    return typeof value === 'number' && global.isNaN(value);\n  }\n\n  function areSameValue(left, right) {\n    if (left === right)\n      return left !== 0 || 1 / left === 1 / right;\n    if (numberIsNaN(left) && numberIsNaN(right))\n      return true;\n\n    return left !== left && right !== right;\n  }\n\n  var createObject = ('__proto__' in {}) ?\n    function(obj) { return obj; } :\n    function(obj) {\n      var proto = obj.__proto__;\n      if (!proto)\n        return obj;\n      var newObject = Object.create(proto);\n      Object.getOwnPropertyNames(obj).forEach(function(name) {\n        Object.defineProperty(newObject, name,\n                             Object.getOwnPropertyDescriptor(obj, name));\n      });\n      return newObject;\n    };\n\n  var identStart = '[\\$_a-zA-Z]';\n  var identPart = '[\\$_a-zA-Z0-9]';\n  var ident = identStart + '+' + identPart + '*';\n  var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)';\n  var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')';\n  var path = '(?:' + identOrElementIndex + ')(?:\\\\s*\\\\.\\\\s*' + identOrElementIndex + ')*';\n  var pathRegExp = new RegExp('^' + path + '$');\n\n  function isPathValid(s) {\n    if (typeof s != 'string')\n      return false;\n    s = s.trim();\n\n    if (s == '')\n      return true;\n\n    if (s[0] == '.')\n      return false;\n\n    return pathRegExp.test(s);\n  }\n\n  var constructorIsPrivate = {};\n\n  function Path(s, privateToken) {\n    if (privateToken !== constructorIsPrivate)\n      throw Error('Use Path.get to retrieve path objects');\n\n    if (s.trim() == '')\n      return this;\n\n    if (isIndex(s)) {\n      this.push(s);\n      return this;\n    }\n\n    s.split(/\\s*\\.\\s*/).filter(function(part) {\n      return part;\n    }).forEach(function(part) {\n      this.push(part);\n    }, this);\n\n    if (hasEval && this.length) {\n      this.getValueFrom = this.compiledGetValueFromFn();\n    }\n  }\n\n  // TODO(rafaelw): Make simple LRU cache\n  var pathCache = {};\n\n  function getPath(pathString) {\n    if (pathString instanceof Path)\n      return pathString;\n\n    if (pathString == null)\n      pathString = '';\n\n    if (typeof pathString !== 'string')\n      pathString = String(pathString);\n\n    var path = pathCache[pathString];\n    if (path)\n      return path;\n    if (!isPathValid(pathString))\n      return invalidPath;\n    var path = new Path(pathString, constructorIsPrivate);\n    pathCache[pathString] = path;\n    return path;\n  }\n\n  Path.get = getPath;\n\n  Path.prototype = createObject({\n    __proto__: [],\n    valid: true,\n\n    toString: function() {\n      return this.join('.');\n    },\n\n    getValueFrom: function(obj, directObserver) {\n      for (var i = 0; i < this.length; i++) {\n        if (obj == null)\n          return;\n        obj = obj[this[i]];\n      }\n      return obj;\n    },\n\n    iterateObjects: function(obj, observe) {\n      for (var i = 0; i < this.length; i++) {\n        if (i)\n          obj = obj[this[i - 1]];\n        if (!obj)\n          return;\n        observe(obj);\n      }\n    },\n\n    compiledGetValueFromFn: function() {\n      var accessors = this.map(function(ident) {\n        return isIndex(ident) ? '[\"' + ident + '\"]' : '.' + ident;\n      });\n\n      var str = '';\n      var pathString = 'obj';\n      str += 'if (obj != null';\n      var i = 0;\n      for (; i < (this.length - 1); i++) {\n        var ident = this[i];\n        pathString += accessors[i];\n        str += ' &&\\n     ' + pathString + ' != null';\n      }\n      str += ')\\n';\n\n      pathString += accessors[i];\n\n      str += '  return ' + pathString + ';\\nelse\\n  return undefined;';\n      return new Function('obj', str);\n    },\n\n    setValueFrom: function(obj, value) {\n      if (!this.length)\n        return false;\n\n      for (var i = 0; i < this.length - 1; i++) {\n        if (!isObject(obj))\n          return false;\n        obj = obj[this[i]];\n      }\n\n      if (!isObject(obj))\n        return false;\n\n      obj[this[i]] = value;\n      return true;\n    }\n  });\n\n  var invalidPath = new Path('', constructorIsPrivate);\n  invalidPath.valid = false;\n  invalidPath.getValueFrom = invalidPath.setValueFrom = function() {};\n\n  var MAX_DIRTY_CHECK_CYCLES = 1000;\n\n  function dirtyCheck(observer) {\n    var cycles = 0;\n    while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {\n      cycles++;\n    }\n    if (global.testingExposeCycleCount)\n      global.dirtyCheckCycleCount = cycles;\n\n    return cycles > 0;\n  }\n\n  function objectIsEmpty(object) {\n    for (var prop in object)\n      return false;\n    return true;\n  }\n\n  function diffIsEmpty(diff) {\n    return objectIsEmpty(diff.added) &&\n           objectIsEmpty(diff.removed) &&\n           objectIsEmpty(diff.changed);\n  }\n\n  function diffObjectFromOldObject(object, oldObject) {\n    var added = {};\n    var removed = {};\n    var changed = {};\n\n    for (var prop in oldObject) {\n      var newValue = object[prop];\n\n      if (newValue !== undefined && newValue === oldObject[prop])\n        continue;\n\n      if (!(prop in object)) {\n        removed[prop] = undefined;\n        continue;\n      }\n\n      if (newValue !== oldObject[prop])\n        changed[prop] = newValue;\n    }\n\n    for (var prop in object) {\n      if (prop in oldObject)\n        continue;\n\n      added[prop] = object[prop];\n    }\n\n    if (Array.isArray(object) && object.length !== oldObject.length)\n      changed.length = object.length;\n\n    return {\n      added: added,\n      removed: removed,\n      changed: changed\n    };\n  }\n\n  var eomTasks = [];\n  function runEOMTasks() {\n    if (!eomTasks.length)\n      return false;\n\n    for (var i = 0; i < eomTasks.length; i++) {\n      eomTasks[i]();\n    }\n    eomTasks.length = 0;\n    return true;\n  }\n\n  var runEOM = hasObserve ? (function(){\n    var eomObj = { pingPong: true };\n    var eomRunScheduled = false;\n\n    Object.observe(eomObj, function() {\n      runEOMTasks();\n      eomRunScheduled = false;\n    });\n\n    return function(fn) {\n      eomTasks.push(fn);\n      if (!eomRunScheduled) {\n        eomRunScheduled = true;\n        eomObj.pingPong = !eomObj.pingPong;\n      }\n    };\n  })() :\n  (function() {\n    return function(fn) {\n      eomTasks.push(fn);\n    };\n  })();\n\n  var observedObjectCache = [];\n\n  function newObservedObject() {\n    var observer;\n    var object;\n    var discardRecords = false;\n    var first = true;\n\n    function callback(records) {\n      if (observer && observer.state_ === OPENED && !discardRecords)\n        observer.check_(records);\n    }\n\n    return {\n      open: function(obs) {\n        if (observer)\n          throw Error('ObservedObject in use');\n\n        if (!first)\n          Object.deliverChangeRecords(callback);\n\n        observer = obs;\n        first = false;\n      },\n      observe: function(obj, arrayObserve) {\n        object = obj;\n        if (arrayObserve)\n          Array.observe(object, callback);\n        else\n          Object.observe(object, callback);\n      },\n      deliver: function(discard) {\n        discardRecords = discard;\n        Object.deliverChangeRecords(callback);\n        discardRecords = false;\n      },\n      close: function() {\n        observer = undefined;\n        Object.unobserve(object, callback);\n        observedObjectCache.push(this);\n      }\n    };\n  }\n\n  function getObservedObject(observer, object, arrayObserve) {\n    var dir = observedObjectCache.pop() || newObservedObject();\n    dir.open(observer);\n    dir.observe(object, arrayObserve);\n    return dir;\n  }\n\n  var emptyArray = [];\n  var observedSetCache = [];\n\n  function newObservedSet() {\n    var observers = [];\n    var observerCount = 0;\n    var objects = [];\n    var toRemove = emptyArray;\n    var resetNeeded = false;\n    var resetScheduled = false;\n\n    function observe(obj) {\n      if (!isObject(obj))\n        return;\n\n      var index = toRemove.indexOf(obj);\n      if (index >= 0) {\n        toRemove[index] = undefined;\n        objects.push(obj);\n      } else if (objects.indexOf(obj) < 0) {\n        objects.push(obj);\n        Object.observe(obj, callback);\n      }\n\n      observe(Object.getPrototypeOf(obj));\n    }\n\n    function reset() {\n      var objs = toRemove === emptyArray ? [] : toRemove;\n      toRemove = objects;\n      objects = objs;\n\n      var observer;\n      for (var id in observers) {\n        observer = observers[id];\n        if (!observer || observer.state_ != OPENED)\n          continue;\n\n        observer.iterateObjects_(observe);\n      }\n\n      for (var i = 0; i < toRemove.length; i++) {\n        var obj = toRemove[i];\n        if (obj)\n          Object.unobserve(obj, callback);\n      }\n\n      toRemove.length = 0;\n    }\n\n    function scheduledReset() {\n      resetScheduled = false;\n      if (!resetNeeded)\n        return;\n\n      reset();\n    }\n\n    function scheduleReset() {\n      if (resetScheduled)\n        return;\n\n      resetNeeded = true;\n      resetScheduled = true;\n      runEOM(scheduledReset);\n    }\n\n    function callback() {\n      reset();\n\n      var observer;\n\n      for (var id in observers) {\n        observer = observers[id];\n        if (!observer || observer.state_ != OPENED)\n          continue;\n\n        observer.check_();\n      }\n    }\n\n    var record = {\n      object: undefined,\n      objects: objects,\n      open: function(obs) {\n        observers[obs.id_] = obs;\n        observerCount++;\n        obs.iterateObjects_(observe);\n      },\n      close: function(obs) {\n        var anyLeft = false;\n\n        observers[obs.id_] = undefined;\n        observerCount--;\n\n        if (observerCount) {\n          scheduleReset();\n          return;\n        }\n        resetNeeded = false;\n\n        for (var i = 0; i < objects.length; i++) {\n          Object.unobserve(objects[i], callback);\n          Observer.unobservedCount++;\n        }\n\n        observers.length = 0;\n        objects.length = 0;\n        observedSetCache.push(this);\n      },\n      reset: scheduleReset\n    };\n\n    return record;\n  }\n\n  var lastObservedSet;\n\n  function getObservedSet(observer, obj) {\n    if (!lastObservedSet || lastObservedSet.object !== obj) {\n      lastObservedSet = observedSetCache.pop() || newObservedSet();\n      lastObservedSet.object = obj;\n    }\n    lastObservedSet.open(observer);\n    return lastObservedSet;\n  }\n\n  var UNOPENED = 0;\n  var OPENED = 1;\n  var CLOSED = 2;\n  var RESETTING = 3;\n\n  var nextObserverId = 1;\n\n  function Observer() {\n    this.state_ = UNOPENED;\n    this.callback_ = undefined;\n    this.target_ = undefined; // TODO(rafaelw): Should be WeakRef\n    this.directObserver_ = undefined;\n    this.value_ = undefined;\n    this.id_ = nextObserverId++;\n  }\n\n  Observer.prototype = {\n    open: function(callback, target) {\n      if (this.state_ != UNOPENED)\n        throw Error('Observer has already been opened.');\n\n      addToAll(this);\n      this.callback_ = callback;\n      this.target_ = target;\n      this.state_ = OPENED;\n      this.connect_();\n      return this.value_;\n    },\n\n    close: function() {\n      if (this.state_ != OPENED)\n        return;\n\n      removeFromAll(this);\n      this.state_ = CLOSED;\n      this.disconnect_();\n      this.value_ = undefined;\n      this.callback_ = undefined;\n      this.target_ = undefined;\n    },\n\n    deliver: function() {\n      if (this.state_ != OPENED)\n        return;\n\n      dirtyCheck(this);\n    },\n\n    report_: function(changes) {\n      try {\n        this.callback_.apply(this.target_, changes);\n      } catch (ex) {\n        Observer._errorThrownDuringCallback = true;\n        console.error('Exception caught during observer callback: ' +\n                       (ex.stack || ex));\n      }\n    },\n\n    discardChanges: function() {\n      this.check_(undefined, true);\n      return this.value_;\n    }\n  }\n\n  var collectObservers = !hasObserve;\n  var allObservers;\n  Observer._allObserversCount = 0;\n\n  if (collectObservers) {\n    allObservers = [];\n  }\n\n  function addToAll(observer) {\n    Observer._allObserversCount++;\n    if (!collectObservers)\n      return;\n\n    allObservers.push(observer);\n  }\n\n  function removeFromAll(observer) {\n    Observer._allObserversCount--;\n  }\n\n  var runningMicrotaskCheckpoint = false;\n\n  var hasDebugForceFullDelivery = typeof Object.deliverAllChangeRecords == 'function';\n\n  global.Platform = global.Platform || {};\n\n  global.Platform.performMicrotaskCheckpoint = function() {\n    if (runningMicrotaskCheckpoint)\n      return;\n\n    if (hasDebugForceFullDelivery) {\n      Object.deliverAllChangeRecords();\n      return;\n    }\n\n    if (!collectObservers)\n      return;\n\n    runningMicrotaskCheckpoint = true;\n\n    var cycles = 0;\n    var anyChanged, toCheck;\n\n    do {\n      cycles++;\n      toCheck = allObservers;\n      allObservers = [];\n      anyChanged = false;\n\n      for (var i = 0; i < toCheck.length; i++) {\n        var observer = toCheck[i];\n        if (observer.state_ != OPENED)\n          continue;\n\n        if (observer.check_())\n          anyChanged = true;\n\n        allObservers.push(observer);\n      }\n      if (runEOMTasks())\n        anyChanged = true;\n    } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);\n\n    if (global.testingExposeCycleCount)\n      global.dirtyCheckCycleCount = cycles;\n\n    runningMicrotaskCheckpoint = false;\n  };\n\n  if (collectObservers) {\n    global.Platform.clearObservers = function() {\n      allObservers = [];\n    };\n  }\n\n  function ObjectObserver(object) {\n    Observer.call(this);\n    this.value_ = object;\n    this.oldObject_ = undefined;\n  }\n\n  ObjectObserver.prototype = createObject({\n    __proto__: Observer.prototype,\n\n    arrayObserve: false,\n\n    connect_: function(callback, target) {\n      if (hasObserve) {\n        this.directObserver_ = getObservedObject(this, this.value_,\n                                                 this.arrayObserve);\n      } else {\n        this.oldObject_ = this.copyObject(this.value_);\n      }\n\n    },\n\n    copyObject: function(object) {\n      var copy = Array.isArray(object) ? [] : {};\n      for (var prop in object) {\n        copy[prop] = object[prop];\n      };\n      if (Array.isArray(object))\n        copy.length = object.length;\n      return copy;\n    },\n\n    check_: function(changeRecords, skipChanges) {\n      var diff;\n      var oldValues;\n      if (hasObserve) {\n        if (!changeRecords)\n          return false;\n\n        oldValues = {};\n        diff = diffObjectFromChangeRecords(this.value_, changeRecords,\n                                           oldValues);\n      } else {\n        oldValues = this.oldObject_;\n        diff = diffObjectFromOldObject(this.value_, this.oldObject_);\n      }\n\n      if (diffIsEmpty(diff))\n        return false;\n\n      if (!hasObserve)\n        this.oldObject_ = this.copyObject(this.value_);\n\n      this.report_([\n        diff.added || {},\n        diff.removed || {},\n        diff.changed || {},\n        function(property) {\n          return oldValues[property];\n        }\n      ]);\n\n      return true;\n    },\n\n    disconnect_: function() {\n      if (hasObserve) {\n        this.directObserver_.close();\n        this.directObserver_ = undefined;\n      } else {\n        this.oldObject_ = undefined;\n      }\n    },\n\n    deliver: function() {\n      if (this.state_ != OPENED)\n        return;\n\n      if (hasObserve)\n        this.directObserver_.deliver(false);\n      else\n        dirtyCheck(this);\n    },\n\n    discardChanges: function() {\n      if (this.directObserver_)\n        this.directObserver_.deliver(true);\n      else\n        this.oldObject_ = this.copyObject(this.value_);\n\n      return this.value_;\n    }\n  });\n\n  function ArrayObserver(array) {\n    if (!Array.isArray(array))\n      throw Error('Provided object is not an Array');\n    ObjectObserver.call(this, array);\n  }\n\n  ArrayObserver.prototype = createObject({\n\n    __proto__: ObjectObserver.prototype,\n\n    arrayObserve: true,\n\n    copyObject: function(arr) {\n      return arr.slice();\n    },\n\n    check_: function(changeRecords) {\n      var splices;\n      if (hasObserve) {\n        if (!changeRecords)\n          return false;\n        splices = projectArraySplices(this.value_, changeRecords);\n      } else {\n        splices = calcSplices(this.value_, 0, this.value_.length,\n                              this.oldObject_, 0, this.oldObject_.length);\n      }\n\n      if (!splices || !splices.length)\n        return false;\n\n      if (!hasObserve)\n        this.oldObject_ = this.copyObject(this.value_);\n\n      this.report_([splices]);\n      return true;\n    }\n  });\n\n  ArrayObserver.applySplices = function(previous, current, splices) {\n    splices.forEach(function(splice) {\n      var spliceArgs = [splice.index, splice.removed.length];\n      var addIndex = splice.index;\n      while (addIndex < splice.index + splice.addedCount) {\n        spliceArgs.push(current[addIndex]);\n        addIndex++;\n      }\n\n      Array.prototype.splice.apply(previous, spliceArgs);\n    });\n  };\n\n  function PathObserver(object, path) {\n    Observer.call(this);\n\n    this.object_ = object;\n    this.path_ = path instanceof Path ? path : getPath(path);\n    this.directObserver_ = undefined;\n  }\n\n  PathObserver.prototype = createObject({\n    __proto__: Observer.prototype,\n\n    connect_: function() {\n      if (hasObserve)\n        this.directObserver_ = getObservedSet(this, this.object_);\n\n      this.check_(undefined, true);\n    },\n\n    disconnect_: function() {\n      this.value_ = undefined;\n\n      if (this.directObserver_) {\n        this.directObserver_.close(this);\n        this.directObserver_ = undefined;\n      }\n    },\n\n    iterateObjects_: function(observe) {\n      this.path_.iterateObjects(this.object_, observe);\n    },\n\n    check_: function(changeRecords, skipChanges) {\n      var oldValue = this.value_;\n      this.value_ = this.path_.getValueFrom(this.object_);\n      if (skipChanges || areSameValue(this.value_, oldValue))\n        return false;\n\n      this.report_([this.value_, oldValue]);\n      return true;\n    },\n\n    setValue: function(newValue) {\n      if (this.path_)\n        this.path_.setValueFrom(this.object_, newValue);\n    }\n  });\n\n  function CompoundObserver() {\n    Observer.call(this);\n\n    this.value_ = [];\n    this.directObserver_ = undefined;\n    this.observed_ = [];\n  }\n\n  var observerSentinel = {};\n\n  CompoundObserver.prototype = createObject({\n    __proto__: Observer.prototype,\n\n    connect_: function() {\n      this.check_(undefined, true);\n\n      if (!hasObserve)\n        return;\n\n      var object;\n      var needsDirectObserver = false;\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        object = this.observed_[i]\n        if (object !== observerSentinel) {\n          needsDirectObserver = true;\n          break;\n        }\n      }\n\n      if (this.directObserver_) {\n        if (needsDirectObserver) {\n          this.directObserver_.reset();\n          return;\n        }\n        this.directObserver_.close();\n        this.directObserver_ = undefined;\n        return;\n      }\n\n      if (needsDirectObserver)\n        this.directObserver_ = getObservedSet(this, object);\n    },\n\n    closeObservers_: function() {\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        if (this.observed_[i] === observerSentinel)\n          this.observed_[i + 1].close();\n      }\n      this.observed_.length = 0;\n    },\n\n    disconnect_: function() {\n      this.value_ = undefined;\n\n      if (this.directObserver_) {\n        this.directObserver_.close(this);\n        this.directObserver_ = undefined;\n      }\n\n      this.closeObservers_();\n    },\n\n    addPath: function(object, path) {\n      if (this.state_ != UNOPENED && this.state_ != RESETTING)\n        throw Error('Cannot add paths once started.');\n\n      this.observed_.push(object, path instanceof Path ? path : getPath(path));\n    },\n\n    addObserver: function(observer) {\n      if (this.state_ != UNOPENED && this.state_ != RESETTING)\n        throw Error('Cannot add observers once started.');\n\n      observer.open(this.deliver, this);\n      this.observed_.push(observerSentinel, observer);\n    },\n\n    startReset: function() {\n      if (this.state_ != OPENED)\n        throw Error('Can only reset while open');\n\n      this.state_ = RESETTING;\n      this.closeObservers_();\n    },\n\n    finishReset: function() {\n      if (this.state_ != RESETTING)\n        throw Error('Can only finishReset after startReset');\n      this.state_ = OPENED;\n      this.connect_();\n\n      return this.value_;\n    },\n\n    iterateObjects_: function(observe) {\n      var object;\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        object = this.observed_[i]\n        if (object !== observerSentinel)\n          this.observed_[i + 1].iterateObjects(object, observe)\n      }\n    },\n\n    check_: function(changeRecords, skipChanges) {\n      var oldValues;\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        var pathOrObserver = this.observed_[i+1];\n        var object = this.observed_[i];\n        var value = object === observerSentinel ?\n            pathOrObserver.discardChanges() :\n            pathOrObserver.getValueFrom(object)\n\n        if (skipChanges) {\n          this.value_[i / 2] = value;\n          continue;\n        }\n\n        if (areSameValue(value, this.value_[i / 2]))\n          continue;\n\n        oldValues = oldValues || [];\n        oldValues[i / 2] = this.value_[i / 2];\n        this.value_[i / 2] = value;\n      }\n\n      if (!oldValues)\n        return false;\n\n      // TODO(rafaelw): Having observed_ as the third callback arg here is\n      // pretty lame API. Fix.\n      this.report_([this.value_, oldValues, this.observed_]);\n      return true;\n    }\n  });\n\n  function identFn(value) { return value; }\n\n  function ObserverTransform(observable, getValueFn, setValueFn,\n                             dontPassThroughSet) {\n    this.callback_ = undefined;\n    this.target_ = undefined;\n    this.value_ = undefined;\n    this.observable_ = observable;\n    this.getValueFn_ = getValueFn || identFn;\n    this.setValueFn_ = setValueFn || identFn;\n    // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this\n    // at the moment because of a bug in it's dependency tracking.\n    this.dontPassThroughSet_ = dontPassThroughSet;\n  }\n\n  ObserverTransform.prototype = {\n    open: function(callback, target) {\n      this.callback_ = callback;\n      this.target_ = target;\n      this.value_ =\n          this.getValueFn_(this.observable_.open(this.observedCallback_, this));\n      return this.value_;\n    },\n\n    observedCallback_: function(value) {\n      value = this.getValueFn_(value);\n      if (areSameValue(value, this.value_))\n        return;\n      var oldValue = this.value_;\n      this.value_ = value;\n      this.callback_.call(this.target_, this.value_, oldValue);\n    },\n\n    discardChanges: function() {\n      this.value_ = this.getValueFn_(this.observable_.discardChanges());\n      return this.value_;\n    },\n\n    deliver: function() {\n      return this.observable_.deliver();\n    },\n\n    setValue: function(value) {\n      value = this.setValueFn_(value);\n      if (!this.dontPassThroughSet_ && this.observable_.setValue)\n        return this.observable_.setValue(value);\n    },\n\n    close: function() {\n      if (this.observable_)\n        this.observable_.close();\n      this.callback_ = undefined;\n      this.target_ = undefined;\n      this.observable_ = undefined;\n      this.value_ = undefined;\n      this.getValueFn_ = undefined;\n      this.setValueFn_ = undefined;\n    }\n  }\n\n  var expectedRecordTypes = {};\n  expectedRecordTypes[PROP_ADD_TYPE] = true;\n  expectedRecordTypes[PROP_UPDATE_TYPE] = true;\n  expectedRecordTypes[PROP_DELETE_TYPE] = true;\n\n  function notifyFunction(object, name) {\n    if (typeof Object.observe !== 'function')\n      return;\n\n    var notifier = Object.getNotifier(object);\n    return function(type, oldValue) {\n      var changeRecord = {\n        object: object,\n        type: type,\n        name: name\n      };\n      if (arguments.length === 2)\n        changeRecord.oldValue = oldValue;\n      notifier.notify(changeRecord);\n    }\n  }\n\n  Observer.defineComputedProperty = function(target, name, observable) {\n    var notify = notifyFunction(target, name);\n    var value = observable.open(function(newValue, oldValue) {\n      value = newValue;\n      if (notify)\n        notify(PROP_UPDATE_TYPE, oldValue);\n    });\n\n    Object.defineProperty(target, name, {\n      get: function() {\n        observable.deliver();\n        return value;\n      },\n      set: function(newValue) {\n        observable.setValue(newValue);\n        return newValue;\n      },\n      configurable: true\n    });\n\n    return {\n      close: function() {\n        observable.close();\n        Object.defineProperty(target, name, {\n          value: value,\n          writable: true,\n          configurable: true\n        });\n      }\n    };\n  }\n\n  function diffObjectFromChangeRecords(object, changeRecords, oldValues) {\n    var added = {};\n    var removed = {};\n\n    for (var i = 0; i < changeRecords.length; i++) {\n      var record = changeRecords[i];\n      if (!expectedRecordTypes[record.type]) {\n        console.error('Unknown changeRecord type: ' + record.type);\n        console.error(record);\n        continue;\n      }\n\n      if (!(record.name in oldValues))\n        oldValues[record.name] = record.oldValue;\n\n      if (record.type == PROP_UPDATE_TYPE)\n        continue;\n\n      if (record.type == PROP_ADD_TYPE) {\n        if (record.name in removed)\n          delete removed[record.name];\n        else\n          added[record.name] = true;\n\n        continue;\n      }\n\n      // type = 'delete'\n      if (record.name in added) {\n        delete added[record.name];\n        delete oldValues[record.name];\n      } else {\n        removed[record.name] = true;\n      }\n    }\n\n    for (var prop in added)\n      added[prop] = object[prop];\n\n    for (var prop in removed)\n      removed[prop] = undefined;\n\n    var changed = {};\n    for (var prop in oldValues) {\n      if (prop in added || prop in removed)\n        continue;\n\n      var newValue = object[prop];\n      if (oldValues[prop] !== newValue)\n        changed[prop] = newValue;\n    }\n\n    return {\n      added: added,\n      removed: removed,\n      changed: changed\n    };\n  }\n\n  function newSplice(index, removed, addedCount) {\n    return {\n      index: index,\n      removed: removed,\n      addedCount: addedCount\n    };\n  }\n\n  var EDIT_LEAVE = 0;\n  var EDIT_UPDATE = 1;\n  var EDIT_ADD = 2;\n  var EDIT_DELETE = 3;\n\n  function ArraySplice() {}\n\n  ArraySplice.prototype = {\n\n    // Note: This function is *based* on the computation of the Levenshtein\n    // \"edit\" distance. The one change is that \"updates\" are treated as two\n    // edits - not one. With Array splices, an update is really a delete\n    // followed by an add. By retaining this, we optimize for \"keeping\" the\n    // maximum array items in the original array. For example:\n    //\n    //   'xxxx123' -> '123yyyy'\n    //\n    // With 1-edit updates, the shortest path would be just to update all seven\n    // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This\n    // leaves the substring '123' intact.\n    calcEditDistances: function(current, currentStart, currentEnd,\n                                old, oldStart, oldEnd) {\n      // \"Deletion\" columns\n      var rowCount = oldEnd - oldStart + 1;\n      var columnCount = currentEnd - currentStart + 1;\n      var distances = new Array(rowCount);\n\n      // \"Addition\" rows. Initialize null column.\n      for (var i = 0; i < rowCount; i++) {\n        distances[i] = new Array(columnCount);\n        distances[i][0] = i;\n      }\n\n      // Initialize null row\n      for (var j = 0; j < columnCount; j++)\n        distances[0][j] = j;\n\n      for (var i = 1; i < rowCount; i++) {\n        for (var j = 1; j < columnCount; j++) {\n          if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))\n            distances[i][j] = distances[i - 1][j - 1];\n          else {\n            var north = distances[i - 1][j] + 1;\n            var west = distances[i][j - 1] + 1;\n            distances[i][j] = north < west ? north : west;\n          }\n        }\n      }\n\n      return distances;\n    },\n\n    // This starts at the final weight, and walks \"backward\" by finding\n    // the minimum previous weight recursively until the origin of the weight\n    // matrix.\n    spliceOperationsFromEditDistances: function(distances) {\n      var i = distances.length - 1;\n      var j = distances[0].length - 1;\n      var current = distances[i][j];\n      var edits = [];\n      while (i > 0 || j > 0) {\n        if (i == 0) {\n          edits.push(EDIT_ADD);\n          j--;\n          continue;\n        }\n        if (j == 0) {\n          edits.push(EDIT_DELETE);\n          i--;\n          continue;\n        }\n        var northWest = distances[i - 1][j - 1];\n        var west = distances[i - 1][j];\n        var north = distances[i][j - 1];\n\n        var min;\n        if (west < north)\n          min = west < northWest ? west : northWest;\n        else\n          min = north < northWest ? north : northWest;\n\n        if (min == northWest) {\n          if (northWest == current) {\n            edits.push(EDIT_LEAVE);\n          } else {\n            edits.push(EDIT_UPDATE);\n            current = northWest;\n          }\n          i--;\n          j--;\n        } else if (min == west) {\n          edits.push(EDIT_DELETE);\n          i--;\n          current = west;\n        } else {\n          edits.push(EDIT_ADD);\n          j--;\n          current = north;\n        }\n      }\n\n      edits.reverse();\n      return edits;\n    },\n\n    /**\n     * Splice Projection functions:\n     *\n     * A splice map is a representation of how a previous array of items\n     * was transformed into a new array of items. Conceptually it is a list of\n     * tuples of\n     *\n     *   <index, removed, addedCount>\n     *\n     * which are kept in ascending index order of. The tuple represents that at\n     * the |index|, |removed| sequence of items were removed, and counting forward\n     * from |index|, |addedCount| items were added.\n     */\n\n    /**\n     * Lacking individual splice mutation information, the minimal set of\n     * splices can be synthesized given the previous state and final state of an\n     * array. The basic approach is to calculate the edit distance matrix and\n     * choose the shortest path through it.\n     *\n     * Complexity: O(l * p)\n     *   l: The length of the current array\n     *   p: The length of the old array\n     */\n    calcSplices: function(current, currentStart, currentEnd,\n                          old, oldStart, oldEnd) {\n      var prefixCount = 0;\n      var suffixCount = 0;\n\n      var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);\n      if (currentStart == 0 && oldStart == 0)\n        prefixCount = this.sharedPrefix(current, old, minLength);\n\n      if (currentEnd == current.length && oldEnd == old.length)\n        suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);\n\n      currentStart += prefixCount;\n      oldStart += prefixCount;\n      currentEnd -= suffixCount;\n      oldEnd -= suffixCount;\n\n      if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)\n        return [];\n\n      if (currentStart == currentEnd) {\n        var splice = newSplice(currentStart, [], 0);\n        while (oldStart < oldEnd)\n          splice.removed.push(old[oldStart++]);\n\n        return [ splice ];\n      } else if (oldStart == oldEnd)\n        return [ newSplice(currentStart, [], currentEnd - currentStart) ];\n\n      var ops = this.spliceOperationsFromEditDistances(\n          this.calcEditDistances(current, currentStart, currentEnd,\n                                 old, oldStart, oldEnd));\n\n      var splice = undefined;\n      var splices = [];\n      var index = currentStart;\n      var oldIndex = oldStart;\n      for (var i = 0; i < ops.length; i++) {\n        switch(ops[i]) {\n          case EDIT_LEAVE:\n            if (splice) {\n              splices.push(splice);\n              splice = undefined;\n            }\n\n            index++;\n            oldIndex++;\n            break;\n          case EDIT_UPDATE:\n            if (!splice)\n              splice = newSplice(index, [], 0);\n\n            splice.addedCount++;\n            index++;\n\n            splice.removed.push(old[oldIndex]);\n            oldIndex++;\n            break;\n          case EDIT_ADD:\n            if (!splice)\n              splice = newSplice(index, [], 0);\n\n            splice.addedCount++;\n            index++;\n            break;\n          case EDIT_DELETE:\n            if (!splice)\n              splice = newSplice(index, [], 0);\n\n            splice.removed.push(old[oldIndex]);\n            oldIndex++;\n            break;\n        }\n      }\n\n      if (splice) {\n        splices.push(splice);\n      }\n      return splices;\n    },\n\n    sharedPrefix: function(current, old, searchLength) {\n      for (var i = 0; i < searchLength; i++)\n        if (!this.equals(current[i], old[i]))\n          return i;\n      return searchLength;\n    },\n\n    sharedSuffix: function(current, old, searchLength) {\n      var index1 = current.length;\n      var index2 = old.length;\n      var count = 0;\n      while (count < searchLength && this.equals(current[--index1], old[--index2]))\n        count++;\n\n      return count;\n    },\n\n    calculateSplices: function(current, previous) {\n      return this.calcSplices(current, 0, current.length, previous, 0,\n                              previous.length);\n    },\n\n    equals: function(currentValue, previousValue) {\n      return currentValue === previousValue;\n    }\n  };\n\n  var arraySplice = new ArraySplice();\n\n  function calcSplices(current, currentStart, currentEnd,\n                       old, oldStart, oldEnd) {\n    return arraySplice.calcSplices(current, currentStart, currentEnd,\n                                   old, oldStart, oldEnd);\n  }\n\n  function intersect(start1, end1, start2, end2) {\n    // Disjoint\n    if (end1 < start2 || end2 < start1)\n      return -1;\n\n    // Adjacent\n    if (end1 == start2 || end2 == start1)\n      return 0;\n\n    // Non-zero intersect, span1 first\n    if (start1 < start2) {\n      if (end1 < end2)\n        return end1 - start2; // Overlap\n      else\n        return end2 - start2; // Contained\n    } else {\n      // Non-zero intersect, span2 first\n      if (end2 < end1)\n        return end2 - start1; // Overlap\n      else\n        return end1 - start1; // Contained\n    }\n  }\n\n  function mergeSplice(splices, index, removed, addedCount) {\n\n    var splice = newSplice(index, removed, addedCount);\n\n    var inserted = false;\n    var insertionOffset = 0;\n\n    for (var i = 0; i < splices.length; i++) {\n      var current = splices[i];\n      current.index += insertionOffset;\n\n      if (inserted)\n        continue;\n\n      var intersectCount = intersect(splice.index,\n                                     splice.index + splice.removed.length,\n                                     current.index,\n                                     current.index + current.addedCount);\n\n      if (intersectCount >= 0) {\n        // Merge the two splices\n\n        splices.splice(i, 1);\n        i--;\n\n        insertionOffset -= current.addedCount - current.removed.length;\n\n        splice.addedCount += current.addedCount - intersectCount;\n        var deleteCount = splice.removed.length +\n                          current.removed.length - intersectCount;\n\n        if (!splice.addedCount && !deleteCount) {\n          // merged splice is a noop. discard.\n          inserted = true;\n        } else {\n          var removed = current.removed;\n\n          if (splice.index < current.index) {\n            // some prefix of splice.removed is prepended to current.removed.\n            var prepend = splice.removed.slice(0, current.index - splice.index);\n            Array.prototype.push.apply(prepend, removed);\n            removed = prepend;\n          }\n\n          if (splice.index + splice.removed.length > current.index + current.addedCount) {\n            // some suffix of splice.removed is appended to current.removed.\n            var append = splice.removed.slice(current.index + current.addedCount - splice.index);\n            Array.prototype.push.apply(removed, append);\n          }\n\n          splice.removed = removed;\n          if (current.index < splice.index) {\n            splice.index = current.index;\n          }\n        }\n      } else if (splice.index < current.index) {\n        // Insert splice here.\n\n        inserted = true;\n\n        splices.splice(i, 0, splice);\n        i++;\n\n        var offset = splice.addedCount - splice.removed.length\n        current.index += offset;\n        insertionOffset += offset;\n      }\n    }\n\n    if (!inserted)\n      splices.push(splice);\n  }\n\n  function createInitialSplices(array, changeRecords) {\n    var splices = [];\n\n    for (var i = 0; i < changeRecords.length; i++) {\n      var record = changeRecords[i];\n      switch(record.type) {\n        case ARRAY_SPLICE_TYPE:\n          mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);\n          break;\n        case PROP_ADD_TYPE:\n        case PROP_UPDATE_TYPE:\n        case PROP_DELETE_TYPE:\n          if (!isIndex(record.name))\n            continue;\n          var index = toNumber(record.name);\n          if (index < 0)\n            continue;\n          mergeSplice(splices, index, [record.oldValue], 1);\n          break;\n        default:\n          console.error('Unexpected record type: ' + JSON.stringify(record));\n          break;\n      }\n    }\n\n    return splices;\n  }\n\n  function projectArraySplices(array, changeRecords) {\n    var splices = [];\n\n    createInitialSplices(array, changeRecords).forEach(function(splice) {\n      if (splice.addedCount == 1 && splice.removed.length == 1) {\n        if (splice.removed[0] !== array[splice.index])\n          splices.push(splice);\n\n        return\n      };\n\n      splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount,\n                                           splice.removed, 0, splice.removed.length));\n    });\n\n    return splices;\n  }\n\n  global.Observer = Observer;\n  global.Observer.runEOM_ = runEOM;\n  global.Observer.hasObjectObserve = hasObserve;\n  global.ArrayObserver = ArrayObserver;\n  global.ArrayObserver.calculateSplices = function(current, previous) {\n    return arraySplice.calculateSplices(current, previous);\n  };\n\n  global.ArraySplice = ArraySplice;\n  global.ObjectObserver = ObjectObserver;\n  global.PathObserver = PathObserver;\n  global.CompoundObserver = CompoundObserver;\n  global.Path = Path;\n  global.ObserverTransform = ObserverTransform;\n\n  // TODO(rafaelw): Only needed for testing until new change record names\n  // make it to release.\n  global.Observer.changeRecordTypes = {\n    add: PROP_ADD_TYPE,\n    update: PROP_UPDATE_TYPE,\n    reconfigure: PROP_RECONFIGURE_TYPE,\n    'delete': PROP_DELETE_TYPE,\n    splice: ARRAY_SPLICE_TYPE\n  };\n})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);\n","// prepoulate window.Platform.flags for default controls\r\nwindow.Platform = window.Platform || {};\r\n// prepopulate window.logFlags if necessary\r\nwindow.logFlags = window.logFlags || {};\r\n// process flags\r\n(function(scope){\r\n  // import\r\n  var flags = scope.flags || {};\r\n  // populate flags from location\r\n  location.search.slice(1).split('&').forEach(function(o) {\r\n    o = o.split('=');\r\n    o[0] && (flags[o[0]] = o[1] || true);\r\n  });\r\n  var entryPoint = document.currentScript || document.querySelector('script[src*=\"platform.js\"]');\r\n  if (entryPoint) {\r\n    var a = entryPoint.attributes;\r\n    for (var i = 0, n; i < a.length; i++) {\r\n      n = a[i];\r\n      if (n.name !== 'src') {\r\n        flags[n.name] = n.value || true;\r\n      }\r\n    }\r\n  }\r\n  if (flags.log) {\r\n    flags.log.split(',').forEach(function(f) {\r\n      window.logFlags[f] = true;\r\n    });\r\n  }\r\n  // If any of these flags match 'native', then force native ShadowDOM; any\r\n  // other truthy value, or failure to detect native\r\n  // ShadowDOM, results in polyfill\r\n  flags.shadow = (flags.shadow || flags.shadowdom || flags.polyfill);\r\n  if (flags.shadow === 'native') {\r\n    flags.shadow = false;\r\n  } else {\r\n    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;\r\n  }\r\n\r\n  // CustomElements polyfill flag\r\n  if (flags.register) {\r\n    window.CustomElements = window.CustomElements || {flags: {}};\r\n    window.CustomElements.flags.register = flags.register;\r\n  }\r\n\r\n  if (flags.imports) {\r\n    window.HTMLImports = window.HTMLImports || {flags: {}};\r\n    window.HTMLImports.flags.imports = flags.imports;\r\n  }\r\n\r\n  // export\r\n  scope.flags = flags;\r\n})(Platform);\r\n\r\n// select ShadowDOM impl\r\nif (Platform.flags.shadow) {\r\n","// Copyright 2012 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\nwindow.ShadowDOMPolyfill = {};\n\n(function(scope) {\n  'use strict';\n\n  var constructorTable = new WeakMap();\n  var nativePrototypeTable = new WeakMap();\n  var wrappers = Object.create(null);\n\n  // Don't test for eval if document has CSP securityPolicy object and we can\n  // see that eval is not supported. This avoids an error message in console\n  // even when the exception is caught\n  var hasEval = !('securityPolicy' in document) ||\n      document.securityPolicy.allowsEval;\n  if (hasEval) {\n    try {\n      var f = new Function('', 'return true;');\n      hasEval = f();\n    } catch (ex) {\n      hasEval = false;\n    }\n  }\n\n  function assert(b) {\n    if (!b)\n      throw new Error('Assertion failed');\n  };\n\n  var defineProperty = Object.defineProperty;\n  var getOwnPropertyNames = Object.getOwnPropertyNames;\n  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n  function mixin(to, from) {\n    getOwnPropertyNames(from).forEach(function(name) {\n      defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n    });\n    return to;\n  };\n\n  function mixinStatics(to, from) {\n    getOwnPropertyNames(from).forEach(function(name) {\n      switch (name) {\n        case 'arguments':\n        case 'caller':\n        case 'length':\n        case 'name':\n        case 'prototype':\n        case 'toString':\n          return;\n      }\n      defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n    });\n    return to;\n  };\n\n  function oneOf(object, propertyNames) {\n    for (var i = 0; i < propertyNames.length; i++) {\n      if (propertyNames[i] in object)\n        return propertyNames[i];\n    }\n  }\n\n  // Mozilla's old DOM bindings are bretty busted:\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=855844\n  // Make sure they are create before we start modifying things.\n  getOwnPropertyNames(window);\n\n  function getWrapperConstructor(node) {\n    var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);\n    var wrapperConstructor = constructorTable.get(nativePrototype);\n    if (wrapperConstructor)\n      return wrapperConstructor;\n\n    var parentWrapperConstructor = getWrapperConstructor(nativePrototype);\n\n    var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, node);\n\n    return GeneratedWrapper;\n  }\n\n  function addForwardingProperties(nativePrototype, wrapperPrototype) {\n    installProperty(nativePrototype, wrapperPrototype, true);\n  }\n\n  function registerInstanceProperties(wrapperPrototype, instanceObject) {\n    installProperty(instanceObject, wrapperPrototype, false);\n  }\n\n  var isFirefox = /Firefox/.test(navigator.userAgent);\n\n  // This is used as a fallback when getting the descriptor fails in\n  // installProperty.\n  var dummyDescriptor = {\n    get: function() {},\n    set: function(v) {},\n    configurable: true,\n    enumerable: true\n  };\n\n  function isEventHandlerName(name) {\n    return /^on[a-z]+$/.test(name);\n  }\n\n  function isIdentifierName(name) {\n    return /^\\w[a-zA-Z_0-9]*$/.test(name);\n  }\n\n  function getGetter(name) {\n    return hasEval && isIdentifierName(name) ?\n        new Function('return this.impl.' + name) :\n        function() { return this.impl[name]; };\n  }\n\n  function getSetter(name) {\n    return hasEval && isIdentifierName(name) ?\n        new Function('v', 'this.impl.' + name + ' = v') :\n        function(v) { this.impl[name] = v; };\n  }\n\n  function getMethod(name) {\n    return hasEval && isIdentifierName(name) ?\n        new Function('return this.impl.' + name +\n                     '.apply(this.impl, arguments)') :\n        function() { return this.impl[name].apply(this.impl, arguments); };\n  }\n\n  function getDescriptor(source, name) {\n    try {\n      return Object.getOwnPropertyDescriptor(source, name);\n    } catch (ex) {\n      // JSC and V8 both use data properties instead of accessors which can\n      // cause getting the property desciptor to throw an exception.\n      // https://bugs.webkit.org/show_bug.cgi?id=49739\n      return dummyDescriptor;\n    }\n  }\n\n  function installProperty(source, target, allowMethod, opt_blacklist) {\n    var names = getOwnPropertyNames(source);\n    for (var i = 0; i < names.length; i++) {\n      var name = names[i];\n      if (name === 'polymerBlackList_')\n        continue;\n\n      if (name in target)\n        continue;\n\n      if (source.polymerBlackList_ && source.polymerBlackList_[name])\n        continue;\n\n      if (isFirefox) {\n        // Tickle Firefox's old bindings.\n        source.__lookupGetter__(name);\n      }\n      var descriptor = getDescriptor(source, name);\n      var getter, setter;\n      if (allowMethod && typeof descriptor.value === 'function') {\n        target[name] = getMethod(name);\n        continue;\n      }\n\n      var isEvent = isEventHandlerName(name);\n      if (isEvent)\n        getter = scope.getEventHandlerGetter(name);\n      else\n        getter = getGetter(name);\n\n      if (descriptor.writable || descriptor.set) {\n        if (isEvent)\n          setter = scope.getEventHandlerSetter(name);\n        else\n          setter = getSetter(name);\n      }\n\n      defineProperty(target, name, {\n        get: getter,\n        set: setter,\n        configurable: descriptor.configurable,\n        enumerable: descriptor.enumerable\n      });\n    }\n  }\n\n  /**\n   * @param {Function} nativeConstructor\n   * @param {Function} wrapperConstructor\n   * @param {Object=} opt_instance If present, this is used to extract\n   *     properties from an instance object.\n   */\n  function register(nativeConstructor, wrapperConstructor, opt_instance) {\n    var nativePrototype = nativeConstructor.prototype;\n    registerInternal(nativePrototype, wrapperConstructor, opt_instance);\n    mixinStatics(wrapperConstructor, nativeConstructor);\n  }\n\n  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {\n    var wrapperPrototype = wrapperConstructor.prototype;\n    assert(constructorTable.get(nativePrototype) === undefined);\n\n    constructorTable.set(nativePrototype, wrapperConstructor);\n    nativePrototypeTable.set(wrapperPrototype, nativePrototype);\n\n    addForwardingProperties(nativePrototype, wrapperPrototype);\n    if (opt_instance)\n      registerInstanceProperties(wrapperPrototype, opt_instance);\n    defineProperty(wrapperPrototype, 'constructor', {\n      value: wrapperConstructor,\n      configurable: true,\n      enumerable: false,\n      writable: true\n    });\n    // Set it again. Some VMs optimizes objects that are used as prototypes.\n    wrapperConstructor.prototype = wrapperPrototype;\n  }\n\n  function isWrapperFor(wrapperConstructor, nativeConstructor) {\n    return constructorTable.get(nativeConstructor.prototype) ===\n        wrapperConstructor;\n  }\n\n  /**\n   * Creates a generic wrapper constructor based on |object| and its\n   * constructor.\n   * @param {Node} object\n   * @return {Function} The generated constructor.\n   */\n  function registerObject(object) {\n    var nativePrototype = Object.getPrototypeOf(object);\n\n    var superWrapperConstructor = getWrapperConstructor(nativePrototype);\n    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, object);\n\n    return GeneratedWrapper;\n  }\n\n  function createWrapperConstructor(superWrapperConstructor) {\n    function GeneratedWrapper(node) {\n      superWrapperConstructor.call(this, node);\n    }\n    var p = Object.create(superWrapperConstructor.prototype);\n    p.constructor = GeneratedWrapper;\n    GeneratedWrapper.prototype = p;\n\n    return GeneratedWrapper;\n  }\n\n  var OriginalDOMImplementation = window.DOMImplementation;\n  var OriginalEventTarget = window.EventTarget;\n  var OriginalEvent = window.Event;\n  var OriginalNode = window.Node;\n  var OriginalWindow = window.Window;\n  var OriginalRange = window.Range;\n  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n  var OriginalSVGElementInstance = window.SVGElementInstance;\n\n  function isWrapper(object) {\n    return object instanceof wrappers.EventTarget ||\n           object instanceof wrappers.Event ||\n           object instanceof wrappers.Range ||\n           object instanceof wrappers.DOMImplementation ||\n           object instanceof wrappers.CanvasRenderingContext2D ||\n           wrappers.WebGLRenderingContext &&\n               object instanceof wrappers.WebGLRenderingContext;\n  }\n\n  function isNative(object) {\n    return OriginalEventTarget && object instanceof OriginalEventTarget ||\n           object instanceof OriginalNode ||\n           object instanceof OriginalEvent ||\n           object instanceof OriginalWindow ||\n           object instanceof OriginalRange ||\n           object instanceof OriginalDOMImplementation ||\n           object instanceof OriginalCanvasRenderingContext2D ||\n           OriginalWebGLRenderingContext &&\n               object instanceof OriginalWebGLRenderingContext ||\n           OriginalSVGElementInstance &&\n               object instanceof OriginalSVGElementInstance;\n  }\n\n  /**\n   * Wraps a node in a WrapperNode. If there already exists a wrapper for the\n   * |node| that wrapper is returned instead.\n   * @param {Node} node\n   * @return {WrapperNode}\n   */\n  function wrap(impl) {\n    if (impl === null)\n      return null;\n\n    assert(isNative(impl));\n    return impl.polymerWrapper_ ||\n        (impl.polymerWrapper_ = new (getWrapperConstructor(impl))(impl));\n  }\n\n  /**\n   * Unwraps a wrapper and returns the node it is wrapping.\n   * @param {WrapperNode} wrapper\n   * @return {Node}\n   */\n  function unwrap(wrapper) {\n    if (wrapper === null)\n      return null;\n    assert(isWrapper(wrapper));\n    return wrapper.impl;\n  }\n\n  /**\n   * Unwraps object if it is a wrapper.\n   * @param {Object} object\n   * @return {Object} The native implementation object.\n   */\n  function unwrapIfNeeded(object) {\n    return object && isWrapper(object) ? unwrap(object) : object;\n  }\n\n  /**\n   * Wraps object if it is not a wrapper.\n   * @param {Object} object\n   * @return {Object} The wrapper for object.\n   */\n  function wrapIfNeeded(object) {\n    return object && !isWrapper(object) ? wrap(object) : object;\n  }\n\n  /**\n   * Overrides the current wrapper (if any) for node.\n   * @param {Node} node\n   * @param {WrapperNode=} wrapper If left out the wrapper will be created as\n   *     needed next time someone wraps the node.\n   */\n  function rewrap(node, wrapper) {\n    if (wrapper === null)\n      return;\n    assert(isNative(node));\n    assert(wrapper === undefined || isWrapper(wrapper));\n    node.polymerWrapper_ = wrapper;\n  }\n\n  function defineGetter(constructor, name, getter) {\n    defineProperty(constructor.prototype, name, {\n      get: getter,\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  function defineWrapGetter(constructor, name) {\n    defineGetter(constructor, name, function() {\n      return wrap(this.impl[name]);\n    });\n  }\n\n  /**\n   * Forwards existing methods on the native object to the wrapper methods.\n   * This does not wrap any of the arguments or the return value since the\n   * wrapper implementation already takes care of that.\n   * @param {Array.<Function>} constructors\n   * @parem {Array.<string>} names\n   */\n  function forwardMethodsToWrapper(constructors, names) {\n    constructors.forEach(function(constructor) {\n      names.forEach(function(name) {\n        constructor.prototype[name] = function() {\n          var w = wrapIfNeeded(this);\n          return w[name].apply(w, arguments);\n        };\n      });\n    });\n  }\n\n  scope.assert = assert;\n  scope.constructorTable = constructorTable;\n  scope.defineGetter = defineGetter;\n  scope.defineWrapGetter = defineWrapGetter;\n  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;\n  scope.isWrapper = isWrapper;\n  scope.isWrapperFor = isWrapperFor;\n  scope.mixin = mixin;\n  scope.nativePrototypeTable = nativePrototypeTable;\n  scope.oneOf = oneOf;\n  scope.registerObject = registerObject;\n  scope.registerWrapper = register;\n  scope.rewrap = rewrap;\n  scope.unwrap = unwrap;\n  scope.unwrapIfNeeded = unwrapIfNeeded;\n  scope.wrap = wrap;\n  scope.wrapIfNeeded = wrapIfNeeded;\n  scope.wrappers = wrappers;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(context) {\n  'use strict';\n\n  var OriginalMutationObserver = window.MutationObserver;\n  var callbacks = [];\n  var pending = false;\n  var timerFunc;\n\n  function handle() {\n    pending = false;\n    var copies = callbacks.slice(0);\n    callbacks = [];\n    for (var i = 0; i < copies.length; i++) {\n      (0, copies[i])();\n    }\n  }\n\n  if (OriginalMutationObserver) {\n    var counter = 1;\n    var observer = new OriginalMutationObserver(handle);\n    var textNode = document.createTextNode(counter);\n    observer.observe(textNode, {characterData: true});\n\n    timerFunc = function() {\n      counter = (counter + 1) % 2;\n      textNode.data = counter;\n    };\n\n  } else {\n    timerFunc = window.setImmediate || window.setTimeout;\n  }\n\n  function setEndOfMicrotask(func) {\n    callbacks.push(func);\n    if (pending)\n      return;\n    pending = true;\n    timerFunc(handle, 0);\n  }\n\n  context.setEndOfMicrotask = setEndOfMicrotask;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var setEndOfMicrotask = scope.setEndOfMicrotask\n  var wrapIfNeeded = scope.wrapIfNeeded\n  var wrappers = scope.wrappers;\n\n  var registrationsTable = new WeakMap();\n  var globalMutationObservers = [];\n  var isScheduled = false;\n\n  function scheduleCallback(observer) {\n    if (isScheduled)\n      return;\n    setEndOfMicrotask(notifyObservers);\n    isScheduled = true;\n  }\n\n  // http://dom.spec.whatwg.org/#mutation-observers\n  function notifyObservers() {\n    isScheduled = false;\n\n    do {\n      var notifyList = globalMutationObservers.slice();\n      var anyNonEmpty = false;\n      for (var i = 0; i < notifyList.length; i++) {\n        var mo = notifyList[i];\n        var queue = mo.takeRecords();\n        removeTransientObserversFor(mo);\n        if (queue.length) {\n          mo.callback_(queue, mo);\n          anyNonEmpty = true;\n        }\n      }\n    } while (anyNonEmpty);\n  }\n\n  /**\n   * @param {string} type\n   * @param {Node} target\n   * @constructor\n   */\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = new wrappers.NodeList();\n    this.removedNodes = new wrappers.NodeList();\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n\n  /**\n   * Registers transient observers to ancestor and its ancesors for the node\n   * which was removed.\n   * @param {!Node} ancestor\n   * @param {!Node} node\n   */\n  function registerTransientObservers(ancestor, node) {\n    for (; ancestor; ancestor = ancestor.parentNode) {\n      var registrations = registrationsTable.get(ancestor);\n      if (!registrations)\n        continue;\n      for (var i = 0; i < registrations.length; i++) {\n        var registration = registrations[i];\n        if (registration.options.subtree)\n          registration.addTransientObserver(node);\n      }\n    }\n  }\n\n  function removeTransientObserversFor(observer) {\n    for (var i = 0; i < observer.nodes_.length; i++) {\n      var node = observer.nodes_[i];\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        return;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        if (registration.observer === observer)\n          registration.removeTransientObservers();\n      }\n    }\n  }\n\n  // http://dom.spec.whatwg.org/#queue-a-mutation-record\n  function enqueueMutation(target, type, data) {\n    // 1.\n    var interestedObservers = Object.create(null);\n    var associatedStrings = Object.create(null);\n\n    // 2.\n    for (var node = target; node; node = node.parentNode) {\n      // 3.\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        continue;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        var options = registration.options;\n        // 1.\n        if (node !== target && !options.subtree)\n          continue;\n\n        // 2.\n        if (type === 'attributes' && !options.attributes)\n          continue;\n\n        // 3. If type is \"attributes\", options's attributeFilter is present, and\n        // either options's attributeFilter does not contain name or namespace\n        // is non-null, continue.\n        if (type === 'attributes' && options.attributeFilter &&\n            (data.namespace !== null ||\n             options.attributeFilter.indexOf(data.name) === -1)) {\n          continue;\n        }\n\n        // 4.\n        if (type === 'characterData' && !options.characterData)\n          continue;\n\n        // 5.\n        if (type === 'childList' && !options.childList)\n          continue;\n\n        // 6.\n        var observer = registration.observer;\n        interestedObservers[observer.uid_] = observer;\n\n        // 7. If either type is \"attributes\" and options's attributeOldValue is\n        // true, or type is \"characterData\" and options's characterDataOldValue\n        // is true, set the paired string of registered observer's observer in\n        // interested observers to oldValue.\n        if (type === 'attributes' && options.attributeOldValue ||\n            type === 'characterData' && options.characterDataOldValue) {\n          associatedStrings[observer.uid_] = data.oldValue;\n        }\n      }\n    }\n\n    var anyRecordsEnqueued = false;\n\n    // 4.\n    for (var uid in interestedObservers) {\n      var observer = interestedObservers[uid];\n      var record = new MutationRecord(type, target);\n\n      // 2.\n      if ('name' in data && 'namespace' in data) {\n        record.attributeName = data.name;\n        record.attributeNamespace = data.namespace;\n      }\n\n      // 3.\n      if (data.addedNodes)\n        record.addedNodes = data.addedNodes;\n\n      // 4.\n      if (data.removedNodes)\n        record.removedNodes = data.removedNodes;\n\n      // 5.\n      if (data.previousSibling)\n        record.previousSibling = data.previousSibling;\n\n      // 6.\n      if (data.nextSibling)\n        record.nextSibling = data.nextSibling;\n\n      // 7.\n      if (associatedStrings[uid] !== undefined)\n        record.oldValue = associatedStrings[uid];\n\n      // 8.\n      observer.records_.push(record);\n\n      anyRecordsEnqueued = true;\n    }\n\n    if (anyRecordsEnqueued)\n      scheduleCallback();\n  }\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * @param {!Object} options\n   * @constructor\n   */\n  function MutationObserverOptions(options) {\n    this.childList = !!options.childList;\n    this.subtree = !!options.subtree;\n\n    // 1. If either options' attributeOldValue or attributeFilter is present\n    // and options' attributes is omitted, set options' attributes to true.\n    if (!('attributes' in options) &&\n        ('attributeOldValue' in options || 'attributeFilter' in options)) {\n      this.attributes = true;\n    } else {\n      this.attributes = !!options.attributes;\n    }\n\n    // 2. If options' characterDataOldValue is present and options'\n    // characterData is omitted, set options' characterData to true.\n    if ('characterDataOldValue' in options && !('characterData' in options))\n      this.characterData = true;\n    else\n      this.characterData = !!options.characterData;\n\n    // 3. & 4.\n    if (!this.attributes &&\n        (options.attributeOldValue || 'attributeFilter' in options) ||\n        // 5.\n        !this.characterData && options.characterDataOldValue) {\n      throw new TypeError();\n    }\n\n    this.characterData = !!options.characterData;\n    this.attributeOldValue = !!options.attributeOldValue;\n    this.characterDataOldValue = !!options.characterDataOldValue;\n    if ('attributeFilter' in options) {\n      if (options.attributeFilter == null ||\n          typeof options.attributeFilter !== 'object') {\n        throw new TypeError();\n      }\n      this.attributeFilter = slice.call(options.attributeFilter);\n    } else {\n      this.attributeFilter = null;\n    }\n  }\n\n  var uidCounter = 0;\n\n  /**\n   * The class that maps to the DOM MutationObserver interface.\n   * @param {Function} callback.\n   * @constructor\n   */\n  function MutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n\n    // This will leak. There is no way to implement this without WeakRefs :'(\n    globalMutationObservers.push(this);\n  }\n\n  MutationObserver.prototype = {\n    // http://dom.spec.whatwg.org/#dom-mutationobserver-observe\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n\n      var newOptions = new MutationObserverOptions(options);\n\n      // 6.\n      var registration;\n      var registrations = registrationsTable.get(target);\n      if (!registrations)\n        registrationsTable.set(target, registrations = []);\n\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          // 6.1.\n          registration.removeTransientObservers();\n          // 6.2.\n          registration.options = newOptions;\n        }\n      }\n\n      // 7.\n      if (!registration) {\n        registration = new Registration(this, target, newOptions);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n    },\n\n    // http://dom.spec.whatwg.org/#dom-mutationobserver-disconnect\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n\n  /**\n   * Class used to represent a registered observer.\n   * @param {MutationObserver} observer\n   * @param {Node} target\n   * @param {MutationObserverOptions} options\n   * @constructor\n   */\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n\n  Registration.prototype = {\n    /**\n     * Adds a transient observer on node. The transient observer gets removed\n     * next time we deliver the change records.\n     * @param {Node} node\n     */\n    addTransientObserver: function(node) {\n      // Don't add transient observers on the target itself. We already have all\n      // the required listeners set up on the target.\n      if (node === this.target)\n        return;\n\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        registrationsTable.set(node, registrations = []);\n\n      // We know that registrations does not contain this because we already\n      // checked if node === this.target.\n      registrations.push(this);\n    },\n\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n\n      for (var i = 0; i < transientObservedNodes.length; i++) {\n        var node = transientObservedNodes[i];\n        var registrations = registrationsTable.get(node);\n        for (var j = 0; j < registrations.length; j++) {\n          if (registrations[j] === this) {\n            registrations.splice(j, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }\n    }\n  };\n\n  scope.enqueueMutation = enqueueMutation;\n  scope.registerTransientObservers = registerTransientObservers;\n  scope.wrappers.MutationObserver = MutationObserver;\n  scope.wrappers.MutationRecord = MutationRecord;\n\n})(window.ShadowDOMPolyfill);\n","/**\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  /**\n   * A tree scope represents the root of a tree. All nodes in a tree point to\n   * the same TreeScope object. The tree scope of a node get set the first time\n   * it is accessed or when a node is added or remove to a tree.\n   * @constructor\n   */\n  function TreeScope(root, parent) {\n    this.root = root;\n    this.parent = parent;\n  }\n\n  TreeScope.prototype = {\n    get renderer() {\n      if (this.root instanceof scope.wrappers.ShadowRoot) {\n        return scope.getRendererForHost(this.root.host);\n      }\n      return null;\n    },\n\n    contains: function(treeScope) {\n      for (; treeScope; treeScope = treeScope.parent) {\n        if (treeScope === this)\n          return true;\n      }\n      return false;\n    }\n  };\n\n  function setTreeScope(node, treeScope) {\n    if (node.treeScope_ !== treeScope) {\n      node.treeScope_ = treeScope;\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        setTreeScope(child, treeScope);\n      }\n    }\n  }\n\n  function getTreeScope(node) {\n    if (node.treeScope_)\n      return node.treeScope_;\n    var parent = node.parentNode;\n    var treeScope;\n    if (parent)\n      treeScope = getTreeScope(parent);\n    else\n      treeScope = new TreeScope(node, null);\n    return node.treeScope_ = treeScope;\n  }\n\n  scope.TreeScope = TreeScope;\n  scope.getTreeScope = getTreeScope;\n  scope.setTreeScope = setTreeScope;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrappers = scope.wrappers;\n\n  var wrappedFuns = new WeakMap();\n  var listenersTable = new WeakMap();\n  var handledEventsTable = new WeakMap();\n  var currentlyDispatchingEvents = new WeakMap();\n  var targetTable = new WeakMap();\n  var currentTargetTable = new WeakMap();\n  var relatedTargetTable = new WeakMap();\n  var eventPhaseTable = new WeakMap();\n  var stopPropagationTable = new WeakMap();\n  var stopImmediatePropagationTable = new WeakMap();\n  var eventHandlersTable = new WeakMap();\n  var eventPathTable = new WeakMap();\n\n  function isShadowRoot(node) {\n    return node instanceof wrappers.ShadowRoot;\n  }\n\n  function isInsertionPoint(node) {\n    var localName = node.localName;\n    return localName === 'content' || localName === 'shadow';\n  }\n\n  function isShadowHost(node) {\n    return !!node.shadowRoot;\n  }\n\n  function getEventParent(node) {\n    var dv;\n    return node.parentNode || (dv = node.defaultView) && wrap(dv) || null;\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-parent\n  function calculateParents(node, context, ancestors) {\n    if (ancestors.length)\n      return ancestors.shift();\n\n    // 1.\n    if (isShadowRoot(node))\n      return getInsertionParent(node) || node.host;\n\n    // 2.\n    var eventParents = scope.eventParentsTable.get(node);\n    if (eventParents) {\n      // Copy over the remaining event parents for next iteration.\n      for (var i = 1; i < eventParents.length; i++) {\n        ancestors[i - 1] = eventParents[i];\n      }\n      return eventParents[0];\n    }\n\n    // 3.\n    if (context && isInsertionPoint(node)) {\n      var parentNode = node.parentNode;\n      if (parentNode && isShadowHost(parentNode)) {\n        var trees = scope.getShadowTrees(parentNode);\n        var p = getInsertionParent(context);\n        for (var i = 0; i < trees.length; i++) {\n          if (trees[i].contains(p))\n            return p;\n        }\n      }\n    }\n\n    return getEventParent(node);\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#event-retargeting\n  function retarget(node) {\n    var stack = [];  // 1.\n    var ancestor = node;  // 2.\n    var targets = [];\n    var ancestors = [];\n    while (ancestor) {  // 3.\n      var context = null;  // 3.2.\n      // TODO(arv): Change order of these. If the stack is empty we always end\n      // up pushing ancestor, no matter what.\n      if (isInsertionPoint(ancestor)) {  // 3.1.\n        context = topMostNotInsertionPoint(stack);  // 3.1.1.\n        var top = stack[stack.length - 1] || ancestor;  // 3.1.2.\n        stack.push(top);\n      } else if (!stack.length) {\n        stack.push(ancestor);  // 3.3.\n      }\n      var target = stack[stack.length - 1];  // 3.4.\n      targets.push({target: target, currentTarget: ancestor});  // 3.5.\n      if (isShadowRoot(ancestor))  // 3.6.\n        stack.pop();  // 3.6.1.\n\n      ancestor = calculateParents(ancestor, context, ancestors);  // 3.7.\n    }\n    return targets;\n  }\n\n  function topMostNotInsertionPoint(stack) {\n    for (var i = stack.length - 1; i >= 0; i--) {\n      if (!isInsertionPoint(stack[i]))\n        return stack[i];\n    }\n    return null;\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-related-target\n  function adjustRelatedTarget(target, related) {\n    var ancestors = [];\n    while (target) {  // 3.\n      var stack = [];  // 3.1.\n      var ancestor = related;  // 3.2.\n      var last = undefined;  // 3.3. Needs to be reset every iteration.\n      while (ancestor) {\n        var context = null;\n        if (!stack.length) {\n          stack.push(ancestor);\n        } else {\n          if (isInsertionPoint(ancestor)) {  // 3.4.3.\n            context = topMostNotInsertionPoint(stack);\n            // isDistributed is more general than checking whether last is\n            // assigned into ancestor.\n            if (isDistributed(last)) {  // 3.4.3.2.\n              var head = stack[stack.length - 1];\n              stack.push(head);\n            }\n          }\n        }\n\n        if (inSameTree(ancestor, target))  // 3.4.4.\n          return stack[stack.length - 1];\n\n        if (isShadowRoot(ancestor))  // 3.4.5.\n          stack.pop();\n\n        last = ancestor;  // 3.4.6.\n        ancestor = calculateParents(ancestor, context, ancestors);  // 3.4.7.\n      }\n      if (isShadowRoot(target))  // 3.5.\n        target = target.host;\n      else\n        target = target.parentNode;  // 3.6.\n    }\n  }\n\n  function getInsertionParent(node) {\n    return scope.insertionParentTable.get(node);\n  }\n\n  function isDistributed(node) {\n    return getInsertionParent(node);\n  }\n\n  function inSameTree(a, b) {\n    return getTreeScope(a) === getTreeScope(b);\n  }\n\n  function dispatchOriginalEvent(originalEvent) {\n    // Make sure this event is only dispatched once.\n    if (handledEventsTable.get(originalEvent))\n      return;\n    handledEventsTable.set(originalEvent, true);\n\n    return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));\n  }\n\n  function dispatchEvent(event, originalWrapperTarget) {\n    if (currentlyDispatchingEvents.get(event))\n      throw new Error('InvalidStateError')\n    currentlyDispatchingEvents.set(event, true);\n\n    // Render to ensure that the event path is correct.\n    scope.renderAllPending();\n    var eventPath = retarget(originalWrapperTarget);\n\n    // For window load events the load event is dispatched at the window but\n    // the target is set to the document.\n    //\n    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end\n    //\n    // TODO(arv): Find a less hacky way to do this.\n    if (event.type === 'load' &&\n        eventPath.length === 2 &&\n        eventPath[0].target instanceof wrappers.Document) {\n      eventPath.shift();\n    }\n\n    eventPathTable.set(event, eventPath);\n\n    if (dispatchCapturing(event, eventPath)) {\n      if (dispatchAtTarget(event, eventPath)) {\n        dispatchBubbling(event, eventPath);\n      }\n    }\n\n    eventPhaseTable.set(event, Event.NONE);\n    currentTargetTable.delete(event, null);\n    currentlyDispatchingEvents.delete(event);\n\n    return event.defaultPrevented;\n  }\n\n  function dispatchCapturing(event, eventPath) {\n    var phase;\n\n    for (var i = eventPath.length - 1; i > 0; i--) {\n      var target = eventPath[i].target;\n      var currentTarget = eventPath[i].currentTarget;\n      if (target === currentTarget)\n        continue;\n\n      phase = Event.CAPTURING_PHASE;\n      if (!invoke(eventPath[i], event, phase))\n        return false;\n    }\n\n    return true;\n  }\n\n  function dispatchAtTarget(event, eventPath) {\n    var phase = Event.AT_TARGET;\n    return invoke(eventPath[0], event, phase);\n  }\n\n  function dispatchBubbling(event, eventPath) {\n    var bubbles = event.bubbles;\n    var phase;\n\n    for (var i = 1; i < eventPath.length; i++) {\n      var target = eventPath[i].target;\n      var currentTarget = eventPath[i].currentTarget;\n      if (target === currentTarget)\n        phase = Event.AT_TARGET;\n      else if (bubbles && !stopImmediatePropagationTable.get(event))\n        phase = Event.BUBBLING_PHASE;\n      else\n        continue;\n\n      if (!invoke(eventPath[i], event, phase))\n        return;\n    }\n  }\n\n  function invoke(tuple, event, phase) {\n    var target = tuple.target;\n    var currentTarget = tuple.currentTarget;\n\n    var listeners = listenersTable.get(currentTarget);\n    if (!listeners)\n      return true;\n\n    if ('relatedTarget' in event) {\n      var originalEvent = unwrap(event);\n      // X-Tag sets relatedTarget on a CustomEvent. If they do that there is no\n      // way to have relatedTarget return the adjusted target but worse is that\n      // the originalEvent might not have a relatedTarget so we hit an assert\n      // when we try to wrap it.\n      if (originalEvent.relatedTarget) {\n        var relatedTarget = wrap(originalEvent.relatedTarget);\n\n        var adjusted = adjustRelatedTarget(currentTarget, relatedTarget);\n        if (adjusted === target)\n          return true;\n\n        relatedTargetTable.set(event, adjusted);\n      }\n    }\n\n    eventPhaseTable.set(event, phase);\n    var type = event.type;\n\n    var anyRemoved = false;\n    targetTable.set(event, target);\n    currentTargetTable.set(event, currentTarget);\n\n    for (var i = 0; i < listeners.length; i++) {\n      var listener = listeners[i];\n      if (listener.removed) {\n        anyRemoved = true;\n        continue;\n      }\n\n      if (listener.type !== type ||\n          !listener.capture && phase === Event.CAPTURING_PHASE ||\n          listener.capture && phase === Event.BUBBLING_PHASE) {\n        continue;\n      }\n\n      try {\n        if (typeof listener.handler === 'function')\n          listener.handler.call(currentTarget, event);\n        else\n          listener.handler.handleEvent(event);\n\n        if (stopImmediatePropagationTable.get(event))\n          return false;\n\n      } catch (ex) {\n        if (window.onerror)\n          window.onerror(ex.message);\n        else\n          console.error(ex, ex.stack);\n      }\n    }\n\n    if (anyRemoved) {\n      var copy = listeners.slice();\n      listeners.length = 0;\n      for (var i = 0; i < copy.length; i++) {\n        if (!copy[i].removed)\n          listeners.push(copy[i]);\n      }\n    }\n\n    return !stopPropagationTable.get(event);\n  }\n\n  function Listener(type, handler, capture) {\n    this.type = type;\n    this.handler = handler;\n    this.capture = Boolean(capture);\n  }\n  Listener.prototype = {\n    equals: function(that) {\n      return this.handler === that.handler && this.type === that.type &&\n          this.capture === that.capture;\n    },\n    get removed() {\n      return this.handler === null;\n    },\n    remove: function() {\n      this.handler = null;\n    }\n  };\n\n  var OriginalEvent = window.Event;\n  OriginalEvent.prototype.polymerBlackList_ = {\n    returnValue: true,\n    // TODO(arv): keyLocation is part of KeyboardEvent but Firefox does not\n    // support constructable KeyboardEvent so we keep it here for now.\n    keyLocation: true\n  };\n\n  /**\n   * Creates a new Event wrapper or wraps an existin native Event object.\n   * @param {string|Event} type\n   * @param {Object=} options\n   * @constructor\n   */\n  function Event(type, options) {\n    if (type instanceof OriginalEvent)\n      this.impl = type;\n    else\n      return wrap(constructEvent(OriginalEvent, 'Event', type, options));\n  }\n  Event.prototype = {\n    get target() {\n      return targetTable.get(this);\n    },\n    get currentTarget() {\n      return currentTargetTable.get(this);\n    },\n    get eventPhase() {\n      return eventPhaseTable.get(this);\n    },\n    get path() {\n      var nodeList = new wrappers.NodeList();\n      var eventPath = eventPathTable.get(this);\n      if (eventPath) {\n        var index = 0;\n        var lastIndex = eventPath.length - 1;\n        var baseRoot = getTreeScope(currentTargetTable.get(this));\n\n        for (var i = 0; i <= lastIndex; i++) {\n          var currentTarget = eventPath[i].currentTarget;\n          var currentRoot = getTreeScope(currentTarget);\n          if (currentRoot.contains(baseRoot) &&\n              // Make sure we do not add Window to the path.\n              (i !== lastIndex || currentTarget instanceof wrappers.Node)) {\n            nodeList[index++] = currentTarget;\n          }\n        }\n        nodeList.length = index;\n      }\n      return nodeList;\n    },\n    stopPropagation: function() {\n      stopPropagationTable.set(this, true);\n    },\n    stopImmediatePropagation: function() {\n      stopPropagationTable.set(this, true);\n      stopImmediatePropagationTable.set(this, true);\n    }\n  };\n  registerWrapper(OriginalEvent, Event, document.createEvent('Event'));\n\n  function unwrapOptions(options) {\n    if (!options || !options.relatedTarget)\n      return options;\n    return Object.create(options, {\n      relatedTarget: {value: unwrap(options.relatedTarget)}\n    });\n  }\n\n  function registerGenericEvent(name, SuperEvent, prototype) {\n    var OriginalEvent = window[name];\n    var GenericEvent = function(type, options) {\n      if (type instanceof OriginalEvent)\n        this.impl = type;\n      else\n        return wrap(constructEvent(OriginalEvent, name, type, options));\n    };\n    GenericEvent.prototype = Object.create(SuperEvent.prototype);\n    if (prototype)\n      mixin(GenericEvent.prototype, prototype);\n    if (OriginalEvent) {\n      // - Old versions of Safari fails on new FocusEvent (and others?).\n      // - IE does not support event constructors.\n      // - createEvent('FocusEvent') throws in Firefox.\n      // => Try the best practice solution first and fallback to the old way\n      // if needed.\n      try {\n        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));\n      } catch (ex) {\n        registerWrapper(OriginalEvent, GenericEvent,\n                        document.createEvent(name));\n      }\n    }\n    return GenericEvent;\n  }\n\n  var UIEvent = registerGenericEvent('UIEvent', Event);\n  var CustomEvent = registerGenericEvent('CustomEvent', Event);\n\n  var relatedTargetProto = {\n    get relatedTarget() {\n      return relatedTargetTable.get(this) || wrap(unwrap(this).relatedTarget);\n    }\n  };\n\n  function getInitFunction(name, relatedTargetIndex) {\n    return function() {\n      arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);\n      var impl = unwrap(this);\n      impl[name].apply(impl, arguments);\n    };\n  }\n\n  var mouseEventProto = mixin({\n    initMouseEvent: getInitFunction('initMouseEvent', 14)\n  }, relatedTargetProto);\n\n  var focusEventProto = mixin({\n    initFocusEvent: getInitFunction('initFocusEvent', 5)\n  }, relatedTargetProto);\n\n  var MouseEvent = registerGenericEvent('MouseEvent', UIEvent, mouseEventProto);\n  var FocusEvent = registerGenericEvent('FocusEvent', UIEvent, focusEventProto);\n\n  // In case the browser does not support event constructors we polyfill that\n  // by calling `createEvent('Foo')` and `initFooEvent` where the arguments to\n  // `initFooEvent` are derived from the registered default event init dict.\n  var defaultInitDicts = Object.create(null);\n\n  var supportsEventConstructors = (function() {\n    try {\n      new window.FocusEvent('focus');\n    } catch (ex) {\n      return false;\n    }\n    return true;\n  })();\n\n  /**\n   * Constructs a new native event.\n   */\n  function constructEvent(OriginalEvent, name, type, options) {\n    if (supportsEventConstructors)\n      return new OriginalEvent(type, unwrapOptions(options));\n\n    // Create the arguments from the default dictionary.\n    var event = unwrap(document.createEvent(name));\n    var defaultDict = defaultInitDicts[name];\n    var args = [type];\n    Object.keys(defaultDict).forEach(function(key) {\n      var v = options != null && key in options ?\n          options[key] : defaultDict[key];\n      if (key === 'relatedTarget')\n        v = unwrap(v);\n      args.push(v);\n    });\n    event['init' + name].apply(event, args);\n    return event;\n  }\n\n  if (!supportsEventConstructors) {\n    var configureEventConstructor = function(name, initDict, superName) {\n      if (superName) {\n        var superDict = defaultInitDicts[superName];\n        initDict = mixin(mixin({}, superDict), initDict);\n      }\n\n      defaultInitDicts[name] = initDict;\n    };\n\n    // The order of the default event init dictionary keys is important, the\n    // arguments to initFooEvent is derived from that.\n    configureEventConstructor('Event', {bubbles: false, cancelable: false});\n    configureEventConstructor('CustomEvent', {detail: null}, 'Event');\n    configureEventConstructor('UIEvent', {view: null, detail: 0}, 'Event');\n    configureEventConstructor('MouseEvent', {\n      screenX: 0,\n      screenY: 0,\n      clientX: 0,\n      clientY: 0,\n      ctrlKey: false,\n      altKey: false,\n      shiftKey: false,\n      metaKey: false,\n      button: 0,\n      relatedTarget: null\n    }, 'UIEvent');\n    configureEventConstructor('FocusEvent', {relatedTarget: null}, 'UIEvent');\n  }\n\n  function BeforeUnloadEvent(impl) {\n    Event.call(this);\n  }\n  BeforeUnloadEvent.prototype = Object.create(Event.prototype);\n  mixin(BeforeUnloadEvent.prototype, {\n    get returnValue() {\n      return this.impl.returnValue;\n    },\n    set returnValue(v) {\n      this.impl.returnValue = v;\n    }\n  });\n\n  function isValidListener(fun) {\n    if (typeof fun === 'function')\n      return true;\n    return fun && fun.handleEvent;\n  }\n\n  function isMutationEvent(type) {\n    switch (type) {\n      case 'DOMAttrModified':\n      case 'DOMAttributeNameChanged':\n      case 'DOMCharacterDataModified':\n      case 'DOMElementNameChanged':\n      case 'DOMNodeInserted':\n      case 'DOMNodeInsertedIntoDocument':\n      case 'DOMNodeRemoved':\n      case 'DOMNodeRemovedFromDocument':\n      case 'DOMSubtreeModified':\n        return true;\n    }\n    return false;\n  }\n\n  var OriginalEventTarget = window.EventTarget;\n\n  /**\n   * This represents a wrapper for an EventTarget.\n   * @param {!EventTarget} impl The original event target.\n   * @constructor\n   */\n  function EventTarget(impl) {\n    this.impl = impl;\n  }\n\n  // Node and Window have different internal type checks in WebKit so we cannot\n  // use the same method as the original function.\n  var methodNames = [\n    'addEventListener',\n    'removeEventListener',\n    'dispatchEvent'\n  ];\n\n  [Node, Window].forEach(function(constructor) {\n    var p = constructor.prototype;\n    methodNames.forEach(function(name) {\n      Object.defineProperty(p, name + '_', {value: p[name]});\n    });\n  });\n\n  function getTargetToListenAt(wrapper) {\n    if (wrapper instanceof wrappers.ShadowRoot)\n      wrapper = wrapper.host;\n    return unwrap(wrapper);\n  }\n\n  EventTarget.prototype = {\n    addEventListener: function(type, fun, capture) {\n      if (!isValidListener(fun) || isMutationEvent(type))\n        return;\n\n      var listener = new Listener(type, fun, capture);\n      var listeners = listenersTable.get(this);\n      if (!listeners) {\n        listeners = [];\n        listenersTable.set(this, listeners);\n      } else {\n        // Might have a duplicate.\n        for (var i = 0; i < listeners.length; i++) {\n          if (listener.equals(listeners[i]))\n            return;\n        }\n      }\n\n      listeners.push(listener);\n\n      var target = getTargetToListenAt(this);\n      target.addEventListener_(type, dispatchOriginalEvent, true);\n    },\n    removeEventListener: function(type, fun, capture) {\n      capture = Boolean(capture);\n      var listeners = listenersTable.get(this);\n      if (!listeners)\n        return;\n      var count = 0, found = false;\n      for (var i = 0; i < listeners.length; i++) {\n        if (listeners[i].type === type && listeners[i].capture === capture) {\n          count++;\n          if (listeners[i].handler === fun) {\n            found = true;\n            listeners[i].remove();\n          }\n        }\n      }\n\n      if (found && count === 1) {\n        var target = getTargetToListenAt(this);\n        target.removeEventListener_(type, dispatchOriginalEvent, true);\n      }\n    },\n    dispatchEvent: function(event) {\n      // We want to use the native dispatchEvent because it triggers the default\n      // actions (like checking a checkbox). However, if there are no listeners\n      // in the composed tree then there are no events that will trigger and\n      // listeners in the non composed tree that are part of the event path are\n      // not notified.\n      //\n      // If we find out that there are no listeners in the composed tree we add\n      // a temporary listener to the target which makes us get called back even\n      // in that case.\n\n      var nativeEvent = unwrap(event);\n      var eventType = nativeEvent.type;\n\n      // Allow dispatching the same event again. This is safe because if user\n      // code calls this during an existing dispatch of the same event the\n      // native dispatchEvent throws (that is required by the spec).\n      handledEventsTable.set(nativeEvent, false);\n\n      // Force rendering since we prefer native dispatch and that works on the\n      // composed tree.\n      scope.renderAllPending();\n\n      var tempListener;\n      if (!hasListenerInAncestors(this, eventType)) {\n        tempListener = function() {};\n        this.addEventListener(eventType, tempListener, true);\n      }\n\n      try {\n        return unwrap(this).dispatchEvent_(nativeEvent);\n      } finally {\n        if (tempListener)\n          this.removeEventListener(eventType, tempListener, true);\n      }\n    }\n  };\n\n  function hasListener(node, type) {\n    var listeners = listenersTable.get(node);\n    if (listeners) {\n      for (var i = 0; i < listeners.length; i++) {\n        if (!listeners[i].removed && listeners[i].type === type)\n          return true;\n      }\n    }\n    return false;\n  }\n\n  function hasListenerInAncestors(target, type) {\n    for (var node = unwrap(target); node; node = node.parentNode) {\n      if (hasListener(wrap(node), type))\n        return true;\n    }\n    return false;\n  }\n\n  if (OriginalEventTarget)\n    registerWrapper(OriginalEventTarget, EventTarget);\n\n  function wrapEventTargetMethods(constructors) {\n    forwardMethodsToWrapper(constructors, methodNames);\n  }\n\n  var originalElementFromPoint = document.elementFromPoint;\n\n  function elementFromPoint(self, document, x, y) {\n    scope.renderAllPending();\n\n    var element = wrap(originalElementFromPoint.call(document.impl, x, y));\n    var targets = retarget(element, this)\n    for (var i = 0; i < targets.length; i++) {\n      var target = targets[i];\n      if (target.currentTarget === self)\n        return target.target;\n    }\n    return null;\n  }\n\n  /**\n   * Returns a function that is to be used as a getter for `onfoo` properties.\n   * @param {string} name\n   * @return {Function}\n   */\n  function getEventHandlerGetter(name) {\n    return function() {\n      var inlineEventHandlers = eventHandlersTable.get(this);\n      return inlineEventHandlers && inlineEventHandlers[name] &&\n          inlineEventHandlers[name].value || null;\n     };\n  }\n\n  /**\n   * Returns a function that is to be used as a setter for `onfoo` properties.\n   * @param {string} name\n   * @return {Function}\n   */\n  function getEventHandlerSetter(name) {\n    var eventType = name.slice(2);\n    return function(value) {\n      var inlineEventHandlers = eventHandlersTable.get(this);\n      if (!inlineEventHandlers) {\n        inlineEventHandlers = Object.create(null);\n        eventHandlersTable.set(this, inlineEventHandlers);\n      }\n\n      var old = inlineEventHandlers[name];\n      if (old)\n        this.removeEventListener(eventType, old.wrapped, false);\n\n      if (typeof value === 'function') {\n        var wrapped = function(e) {\n          var rv = value.call(this, e);\n          if (rv === false)\n            e.preventDefault();\n          else if (name === 'onbeforeunload' && typeof rv === 'string')\n            e.returnValue = rv;\n          // mouseover uses true for preventDefault but preventDefault for\n          // mouseover is ignored by browsers these day.\n        };\n\n        this.addEventListener(eventType, wrapped, false);\n        inlineEventHandlers[name] = {\n          value: value,\n          wrapped: wrapped\n        };\n      }\n    };\n  }\n\n  scope.adjustRelatedTarget = adjustRelatedTarget;\n  scope.elementFromPoint = elementFromPoint;\n  scope.getEventHandlerGetter = getEventHandlerGetter;\n  scope.getEventHandlerSetter = getEventHandlerSetter;\n  scope.wrapEventTargetMethods = wrapEventTargetMethods;\n  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;\n  scope.wrappers.CustomEvent = CustomEvent;\n  scope.wrappers.Event = Event;\n  scope.wrappers.EventTarget = EventTarget;\n  scope.wrappers.FocusEvent = FocusEvent;\n  scope.wrappers.MouseEvent = MouseEvent;\n  scope.wrappers.UIEvent = UIEvent;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2012 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var wrap = scope.wrap;\n\n  function nonEnum(obj, prop) {\n    Object.defineProperty(obj, prop, {enumerable: false});\n  }\n\n  function NodeList() {\n    this.length = 0;\n    nonEnum(this, 'length');\n  }\n  NodeList.prototype = {\n    item: function(index) {\n      return this[index];\n    }\n  };\n  nonEnum(NodeList.prototype, 'item');\n\n  function wrapNodeList(list) {\n    if (list == null)\n      return list;\n    var wrapperList = new NodeList();\n    for (var i = 0, length = list.length; i < length; i++) {\n      wrapperList[i] = wrap(list[i]);\n    }\n    wrapperList.length = length;\n    return wrapperList;\n  }\n\n  function addWrapNodeListMethod(wrapperConstructor, name) {\n    wrapperConstructor.prototype[name] = function() {\n      return wrapNodeList(this.impl[name].apply(this.impl, arguments));\n    };\n  }\n\n  scope.wrappers.NodeList = NodeList;\n  scope.addWrapNodeListMethod = addWrapNodeListMethod;\n  scope.wrapNodeList = wrapNodeList;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  // TODO(arv): Implement.\n\n  scope.wrapHTMLCollection = scope.wrapNodeList;\n  scope.wrappers.HTMLCollection = scope.wrappers.NodeList;\n\n})(window.ShadowDOMPolyfill);\n","/**\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var EventTarget = scope.wrappers.EventTarget;\n  var NodeList = scope.wrappers.NodeList;\n  var TreeScope = scope.TreeScope;\n  var assert = scope.assert;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var enqueueMutation = scope.enqueueMutation;\n  var getTreeScope = scope.getTreeScope;\n  var isWrapper = scope.isWrapper;\n  var mixin = scope.mixin;\n  var registerTransientObservers = scope.registerTransientObservers;\n  var registerWrapper = scope.registerWrapper;\n  var setTreeScope = scope.setTreeScope;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapIfNeeded = scope.wrapIfNeeded;\n  var wrappers = scope.wrappers;\n\n  function assertIsNodeWrapper(node) {\n    assert(node instanceof Node);\n  }\n\n  function createOneElementNodeList(node) {\n    var nodes = new NodeList();\n    nodes[0] = node;\n    nodes.length = 1;\n    return nodes;\n  }\n\n  var surpressMutations = false;\n\n  /**\n   * Called before node is inserted into a node to enqueue its removal from its\n   * old parent.\n   * @param {!Node} node The node that is about to be removed.\n   * @param {!Node} parent The parent node that the node is being removed from.\n   * @param {!NodeList} nodes The collected nodes.\n   */\n  function enqueueRemovalForInsertedNodes(node, parent, nodes) {\n    enqueueMutation(parent, 'childList', {\n      removedNodes: nodes,\n      previousSibling: node.previousSibling,\n      nextSibling: node.nextSibling\n    });\n  }\n\n  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {\n    enqueueMutation(df, 'childList', {\n      removedNodes: nodes\n    });\n  }\n\n  /**\n   * Collects nodes from a DocumentFragment or a Node for removal followed\n   * by an insertion.\n   *\n   * This updates the internal pointers for node, previousNode and nextNode.\n   */\n  function collectNodes(node, parentNode, previousNode, nextNode) {\n    if (node instanceof DocumentFragment) {\n      var nodes = collectNodesForDocumentFragment(node);\n\n      // The extra loop is to work around bugs with DocumentFragments in IE.\n      surpressMutations = true;\n      for (var i = nodes.length - 1; i >= 0; i--) {\n        node.removeChild(nodes[i]);\n        nodes[i].parentNode_ = parentNode;\n      }\n      surpressMutations = false;\n\n      for (var i = 0; i < nodes.length; i++) {\n        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;\n        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;\n      }\n\n      if (previousNode)\n        previousNode.nextSibling_ = nodes[0];\n      if (nextNode)\n        nextNode.previousSibling_ = nodes[nodes.length - 1];\n\n      return nodes;\n    }\n\n    var nodes = createOneElementNodeList(node);\n    var oldParent = node.parentNode;\n    if (oldParent) {\n      // This will enqueue the mutation record for the removal as needed.\n      oldParent.removeChild(node);\n    }\n\n    node.parentNode_ = parentNode;\n    node.previousSibling_ = previousNode;\n    node.nextSibling_ = nextNode;\n    if (previousNode)\n      previousNode.nextSibling_ = node;\n    if (nextNode)\n      nextNode.previousSibling_ = node;\n\n    return nodes;\n  }\n\n  function collectNodesNative(node) {\n    if (node instanceof DocumentFragment)\n      return collectNodesForDocumentFragment(node);\n\n    var nodes = createOneElementNodeList(node);\n    var oldParent = node.parentNode;\n    if (oldParent)\n      enqueueRemovalForInsertedNodes(node, oldParent, nodes);\n    return nodes;\n  }\n\n  function collectNodesForDocumentFragment(node) {\n    var nodes = new NodeList();\n    var i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      nodes[i++] = child;\n    }\n    nodes.length = i;\n    enqueueRemovalForInsertedDocumentFragment(node, nodes);\n    return nodes;\n  }\n\n  function snapshotNodeList(nodeList) {\n    // NodeLists are not live at the moment so just return the same object.\n    return nodeList;\n  }\n\n  // http://dom.spec.whatwg.org/#node-is-inserted\n  function nodeWasAdded(node, treeScope) {\n    setTreeScope(node, treeScope);\n    node.nodeIsInserted_();\n  }\n\n  function nodesWereAdded(nodes, parent) {\n    var treeScope = getTreeScope(parent);\n    for (var i = 0; i < nodes.length; i++) {\n      nodeWasAdded(nodes[i], treeScope);\n    }\n  }\n\n  // http://dom.spec.whatwg.org/#node-is-removed\n  function nodeWasRemoved(node) {\n    setTreeScope(node, new TreeScope(node, null));\n  }\n\n  function nodesWereRemoved(nodes) {\n    for (var i = 0; i < nodes.length; i++) {\n      nodeWasRemoved(nodes[i]);\n    }\n  }\n\n  function ensureSameOwnerDocument(parent, child) {\n    var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ?\n        parent : parent.ownerDocument;\n    if (ownerDoc !== child.ownerDocument)\n      ownerDoc.adoptNode(child);\n  }\n\n  function adoptNodesIfNeeded(owner, nodes) {\n    if (!nodes.length)\n      return;\n\n    var ownerDoc = owner.ownerDocument;\n\n    // All nodes have the same ownerDocument when we get here.\n    if (ownerDoc === nodes[0].ownerDocument)\n      return;\n\n    for (var i = 0; i < nodes.length; i++) {\n      scope.adoptNodeNoRemove(nodes[i], ownerDoc);\n    }\n  }\n\n  function unwrapNodesForInsertion(owner, nodes) {\n    adoptNodesIfNeeded(owner, nodes);\n    var length = nodes.length;\n\n    if (length === 1)\n      return unwrap(nodes[0]);\n\n    var df = unwrap(owner.ownerDocument.createDocumentFragment());\n    for (var i = 0; i < length; i++) {\n      df.appendChild(unwrap(nodes[i]));\n    }\n    return df;\n  }\n\n  function clearChildNodes(wrapper) {\n    if (wrapper.firstChild_ !== undefined) {\n      var child = wrapper.firstChild_;\n      while (child) {\n        var tmp = child;\n        child = child.nextSibling_;\n        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;\n      }\n    }\n    wrapper.firstChild_ = wrapper.lastChild_ = undefined;\n  }\n\n  function removeAllChildNodes(wrapper) {\n    if (wrapper.invalidateShadowRenderer()) {\n      var childWrapper = wrapper.firstChild;\n      while (childWrapper) {\n        assert(childWrapper.parentNode === wrapper);\n        var nextSibling = childWrapper.nextSibling;\n        var childNode = unwrap(childWrapper);\n        var parentNode = childNode.parentNode;\n        if (parentNode)\n          originalRemoveChild.call(parentNode, childNode);\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ =\n            childWrapper.parentNode_ = null;\n        childWrapper = nextSibling;\n      }\n      wrapper.firstChild_ = wrapper.lastChild_ = null;\n    } else {\n      var node = unwrap(wrapper);\n      var child = node.firstChild;\n      var nextSibling;\n      while (child) {\n        nextSibling = child.nextSibling;\n        originalRemoveChild.call(node, child);\n        child = nextSibling;\n      }\n    }\n  }\n\n  function invalidateParent(node) {\n    var p = node.parentNode;\n    return p && p.invalidateShadowRenderer();\n  }\n\n  function cleanupNodes(nodes) {\n    for (var i = 0, n; i < nodes.length; i++) {\n      n = nodes[i];\n      n.parentNode.removeChild(n);\n    }\n  }\n\n  var originalImportNode = document.importNode;\n  var originalCloneNode = window.Node.prototype.cloneNode;\n\n  function cloneNode(node, deep, opt_doc) {\n    var clone;\n    if (opt_doc)\n      clone = wrap(originalImportNode.call(opt_doc, node.impl, false));\n    else\n      clone = wrap(originalCloneNode.call(node.impl, false));\n\n    if (deep) {\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        clone.appendChild(cloneNode(child, true, opt_doc));\n      }\n\n      if (node instanceof wrappers.HTMLTemplateElement) {\n        var cloneContent = clone.content;\n        for (var child = node.content.firstChild;\n             child;\n             child = child.nextSibling) {\n         cloneContent.appendChild(cloneNode(child, true, opt_doc));\n        }\n      }\n    }\n    // TODO(arv): Some HTML elements also clone other data like value.\n    return clone;\n  }\n\n  function contains(self, child) {\n    if (!child || getTreeScope(self) !== getTreeScope(child))\n      return false;\n\n    for (var node = child; node; node = node.parentNode) {\n      if (node === self)\n        return true;\n    }\n    return false;\n  }\n\n  var OriginalNode = window.Node;\n\n  /**\n   * This represents a wrapper of a native DOM node.\n   * @param {!Node} original The original DOM node, aka, the visual DOM node.\n   * @constructor\n   * @extends {EventTarget}\n   */\n  function Node(original) {\n    assert(original instanceof OriginalNode);\n\n    EventTarget.call(this, original);\n\n    // These properties are used to override the visual references with the\n    // logical ones. If the value is undefined it means that the logical is the\n    // same as the visual.\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.parentNode_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.firstChild_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.lastChild_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.nextSibling_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.previousSibling_ = undefined;\n\n    this.treeScope_ = undefined;\n  }\n\n  var OriginalDocumentFragment = window.DocumentFragment;\n  var originalAppendChild = OriginalNode.prototype.appendChild;\n  var originalCompareDocumentPosition =\n      OriginalNode.prototype.compareDocumentPosition;\n  var originalInsertBefore = OriginalNode.prototype.insertBefore;\n  var originalRemoveChild = OriginalNode.prototype.removeChild;\n  var originalReplaceChild = OriginalNode.prototype.replaceChild;\n\n  var isIe = /Trident/.test(navigator.userAgent);\n\n  var removeChildOriginalHelper = isIe ?\n      function(parent, child) {\n        try {\n          originalRemoveChild.call(parent, child);\n        } catch (ex) {\n          if (!(parent instanceof OriginalDocumentFragment))\n            throw ex;\n        }\n      } :\n      function(parent, child) {\n        originalRemoveChild.call(parent, child);\n      };\n\n  Node.prototype = Object.create(EventTarget.prototype);\n  mixin(Node.prototype, {\n    appendChild: function(childWrapper) {\n      return this.insertBefore(childWrapper, null);\n    },\n\n    insertBefore: function(childWrapper, refWrapper) {\n      assertIsNodeWrapper(childWrapper);\n\n      var refNode;\n      if (refWrapper) {\n        if (isWrapper(refWrapper)) {\n          refNode = unwrap(refWrapper);\n        } else {\n          refNode = refWrapper;\n          refWrapper = wrap(refNode);\n        }\n      } else {\n        refWrapper = null;\n        refNode = null;\n      }\n\n      refWrapper && assert(refWrapper.parentNode === this);\n\n      var nodes;\n      var previousNode =\n          refWrapper ? refWrapper.previousSibling : this.lastChild;\n\n      var useNative = !this.invalidateShadowRenderer() &&\n                      !invalidateParent(childWrapper);\n\n      if (useNative)\n        nodes = collectNodesNative(childWrapper);\n      else\n        nodes = collectNodes(childWrapper, this, previousNode, refWrapper);\n\n      if (useNative) {\n        ensureSameOwnerDocument(this, childWrapper);\n        clearChildNodes(this);\n        originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);\n      } else {\n        if (!previousNode)\n          this.firstChild_ = nodes[0];\n        if (!refWrapper)\n          this.lastChild_ = nodes[nodes.length - 1];\n\n        var parentNode = refNode ? refNode.parentNode : this.impl;\n\n        // insertBefore refWrapper no matter what the parent is?\n        if (parentNode) {\n          originalInsertBefore.call(parentNode,\n              unwrapNodesForInsertion(this, nodes), refNode);\n        } else {\n          adoptNodesIfNeeded(this, nodes);\n        }\n      }\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: nodes,\n        nextSibling: refWrapper,\n        previousSibling: previousNode\n      });\n\n      nodesWereAdded(nodes, this);\n\n      return childWrapper;\n    },\n\n    removeChild: function(childWrapper) {\n      assertIsNodeWrapper(childWrapper);\n      if (childWrapper.parentNode !== this) {\n        // IE has invalid DOM trees at times.\n        var found = false;\n        var childNodes = this.childNodes;\n        for (var ieChild = this.firstChild; ieChild;\n             ieChild = ieChild.nextSibling) {\n          if (ieChild === childWrapper) {\n            found = true;\n            break;\n          }\n        }\n        if (!found) {\n          // TODO(arv): DOMException\n          throw new Error('NotFoundError');\n        }\n      }\n\n      var childNode = unwrap(childWrapper);\n      var childWrapperNextSibling = childWrapper.nextSibling;\n      var childWrapperPreviousSibling = childWrapper.previousSibling;\n\n      if (this.invalidateShadowRenderer()) {\n        // We need to remove the real node from the DOM before updating the\n        // pointers. This is so that that mutation event is dispatched before\n        // the pointers have changed.\n        var thisFirstChild = this.firstChild;\n        var thisLastChild = this.lastChild;\n\n        var parentNode = childNode.parentNode;\n        if (parentNode)\n          removeChildOriginalHelper(parentNode, childNode);\n\n        if (thisFirstChild === childWrapper)\n          this.firstChild_ = childWrapperNextSibling;\n        if (thisLastChild === childWrapper)\n          this.lastChild_ = childWrapperPreviousSibling;\n        if (childWrapperPreviousSibling)\n          childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;\n        if (childWrapperNextSibling) {\n          childWrapperNextSibling.previousSibling_ =\n              childWrapperPreviousSibling;\n        }\n\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ =\n            childWrapper.parentNode_ = undefined;\n      } else {\n        clearChildNodes(this);\n        removeChildOriginalHelper(this.impl, childNode);\n      }\n\n      if (!surpressMutations) {\n        enqueueMutation(this, 'childList', {\n          removedNodes: createOneElementNodeList(childWrapper),\n          nextSibling: childWrapperNextSibling,\n          previousSibling: childWrapperPreviousSibling\n        });\n      }\n\n      registerTransientObservers(this, childWrapper);\n\n      return childWrapper;\n    },\n\n    replaceChild: function(newChildWrapper, oldChildWrapper) {\n      assertIsNodeWrapper(newChildWrapper);\n\n      var oldChildNode;\n      if (isWrapper(oldChildWrapper)) {\n        oldChildNode = unwrap(oldChildWrapper);\n      } else {\n        oldChildNode = oldChildWrapper;\n        oldChildWrapper = wrap(oldChildNode);\n      }\n\n      if (oldChildWrapper.parentNode !== this) {\n        // TODO(arv): DOMException\n        throw new Error('NotFoundError');\n      }\n\n      var nextNode = oldChildWrapper.nextSibling;\n      var previousNode = oldChildWrapper.previousSibling;\n      var nodes;\n\n      var useNative = !this.invalidateShadowRenderer() &&\n                      !invalidateParent(newChildWrapper);\n\n      if (useNative) {\n        nodes = collectNodesNative(newChildWrapper);\n      } else {\n        if (nextNode === newChildWrapper)\n          nextNode = newChildWrapper.nextSibling;\n        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);\n      }\n\n      if (!useNative) {\n        if (this.firstChild === oldChildWrapper)\n          this.firstChild_ = nodes[0];\n        if (this.lastChild === oldChildWrapper)\n          this.lastChild_ = nodes[nodes.length - 1];\n\n        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ =\n            oldChildWrapper.parentNode_ = undefined;\n\n        // replaceChild no matter what the parent is?\n        if (oldChildNode.parentNode) {\n          originalReplaceChild.call(\n              oldChildNode.parentNode,\n              unwrapNodesForInsertion(this, nodes),\n              oldChildNode);\n        }\n      } else {\n        ensureSameOwnerDocument(this, newChildWrapper);\n        clearChildNodes(this);\n        originalReplaceChild.call(this.impl, unwrap(newChildWrapper),\n                                  oldChildNode);\n      }\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: nodes,\n        removedNodes: createOneElementNodeList(oldChildWrapper),\n        nextSibling: nextNode,\n        previousSibling: previousNode\n      });\n\n      nodeWasRemoved(oldChildWrapper);\n      nodesWereAdded(nodes, this);\n\n      return oldChildWrapper;\n    },\n\n    /**\n     * Called after a node was inserted. Subclasses override this to invalidate\n     * the renderer as needed.\n     * @private\n     */\n    nodeIsInserted_: function() {\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        child.nodeIsInserted_();\n      }\n    },\n\n    hasChildNodes: function() {\n      return this.firstChild !== null;\n    },\n\n    /** @type {Node} */\n    get parentNode() {\n      // If the parentNode has not been overridden, use the original parentNode.\n      return this.parentNode_ !== undefined ?\n          this.parentNode_ : wrap(this.impl.parentNode);\n    },\n\n    /** @type {Node} */\n    get firstChild() {\n      return this.firstChild_ !== undefined ?\n          this.firstChild_ : wrap(this.impl.firstChild);\n    },\n\n    /** @type {Node} */\n    get lastChild() {\n      return this.lastChild_ !== undefined ?\n          this.lastChild_ : wrap(this.impl.lastChild);\n    },\n\n    /** @type {Node} */\n    get nextSibling() {\n      return this.nextSibling_ !== undefined ?\n          this.nextSibling_ : wrap(this.impl.nextSibling);\n    },\n\n    /** @type {Node} */\n    get previousSibling() {\n      return this.previousSibling_ !== undefined ?\n          this.previousSibling_ : wrap(this.impl.previousSibling);\n    },\n\n    get parentElement() {\n      var p = this.parentNode;\n      while (p && p.nodeType !== Node.ELEMENT_NODE) {\n        p = p.parentNode;\n      }\n      return p;\n    },\n\n    get textContent() {\n      // TODO(arv): This should fallback to this.impl.textContent if there\n      // are no shadow trees below or above the context node.\n      var s = '';\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        if (child.nodeType != Node.COMMENT_NODE) {\n          s += child.textContent;\n        }\n      }\n      return s;\n    },\n    set textContent(textContent) {\n      var removedNodes = snapshotNodeList(this.childNodes);\n\n      if (this.invalidateShadowRenderer()) {\n        removeAllChildNodes(this);\n        if (textContent !== '') {\n          var textNode = this.impl.ownerDocument.createTextNode(textContent);\n          this.appendChild(textNode);\n        }\n      } else {\n        clearChildNodes(this);\n        this.impl.textContent = textContent;\n      }\n\n      var addedNodes = snapshotNodeList(this.childNodes);\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: addedNodes,\n        removedNodes: removedNodes\n      });\n\n      nodesWereRemoved(removedNodes);\n      nodesWereAdded(addedNodes, this);\n    },\n\n    get childNodes() {\n      var wrapperList = new NodeList();\n      var i = 0;\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        wrapperList[i++] = child;\n      }\n      wrapperList.length = i;\n      return wrapperList;\n    },\n\n    cloneNode: function(deep) {\n      return cloneNode(this, deep);\n    },\n\n    contains: function(child) {\n      return contains(this, wrapIfNeeded(child));\n    },\n\n    compareDocumentPosition: function(otherNode) {\n      // This only wraps, it therefore only operates on the composed DOM and not\n      // the logical DOM.\n      return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));\n    },\n\n    normalize: function() {\n      var nodes = snapshotNodeList(this.childNodes);\n      var remNodes = [];\n      var s = '';\n      var modNode;\n\n      for (var i = 0, n; i < nodes.length; i++) {\n        n = nodes[i];\n        if (n.nodeType === Node.TEXT_NODE) {\n          if (!modNode && !n.data.length)\n            this.removeNode(n);\n          else if (!modNode)\n            modNode = n;\n          else {\n            s += n.data;\n            remNodes.push(n);\n          }\n        } else {\n          if (modNode && remNodes.length) {\n            modNode.data += s;\n            cleanUpNodes(remNodes);\n          }\n          remNodes = [];\n          s = '';\n          modNode = null;\n          if (n.childNodes.length)\n            n.normalize();\n        }\n      }\n\n      // handle case where >1 text nodes are the last children\n      if (modNode && remNodes.length) {\n        modNode.data += s;\n        cleanupNodes(remNodes);\n      }\n    }\n  });\n\n  defineWrapGetter(Node, 'ownerDocument');\n\n  // We use a DocumentFragment as a base and then delete the properties of\n  // DocumentFragment.prototype from the wrapper Node. Since delete makes\n  // objects slow in some JS engines we recreate the prototype object.\n  registerWrapper(OriginalNode, Node, document.createDocumentFragment());\n  delete Node.prototype.querySelector;\n  delete Node.prototype.querySelectorAll;\n  Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);\n\n  scope.cloneNode = cloneNode;\n  scope.nodeWasAdded = nodeWasAdded;\n  scope.nodeWasRemoved = nodeWasRemoved;\n  scope.nodesWereAdded = nodesWereAdded;\n  scope.nodesWereRemoved = nodesWereRemoved;\n  scope.snapshotNodeList = snapshotNodeList;\n  scope.wrappers.Node = Node;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  function findOne(node, selector) {\n    var m, el = node.firstElementChild;\n    while (el) {\n      if (el.matches(selector))\n        return el;\n      m = findOne(el, selector);\n      if (m)\n        return m;\n      el = el.nextElementSibling;\n    }\n    return null;\n  }\n\n  function findAll(node, selector, results) {\n    var el = node.firstElementChild;\n    while (el) {\n      if (el.matches(selector))\n        results[results.length++] = el;\n      findAll(el, selector, results);\n      el = el.nextElementSibling;\n    }\n    return results;\n  }\n\n  // find and findAll will only match Simple Selectors,\n  // Structural Pseudo Classes are not guarenteed to be correct\n  // http://www.w3.org/TR/css3-selectors/#simple-selectors\n\n  var SelectorsInterface = {\n    querySelector: function(selector) {\n      return findOne(this, selector);\n    },\n    querySelectorAll: function(selector) {\n      return findAll(this, selector, new NodeList())\n    }\n  };\n\n  var GetElementsByInterface = {\n    getElementsByTagName: function(tagName) {\n      // TODO(arv): Check tagName?\n      return this.querySelectorAll(tagName);\n    },\n    getElementsByClassName: function(className) {\n      // TODO(arv): Check className?\n      return this.querySelectorAll('.' + className);\n    },\n    getElementsByTagNameNS: function(ns, tagName) {\n      if (ns === '*')\n        return this.getElementsByTagName(tagName);\n\n      // TODO(arv): Check tagName?\n      var result = new NodeList;\n      var els = this.getElementsByTagName(tagName);\n      for (var i = 0, j = 0; i < els.length; i++) {\n        if (els[i].namespaceURI === ns)\n          result[j++] = els[i];\n      }\n      result.length = j;\n      return result;\n    }\n  };\n\n  scope.GetElementsByInterface = GetElementsByInterface;\n  scope.SelectorsInterface = SelectorsInterface;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var NodeList = scope.wrappers.NodeList;\n\n  function forwardElement(node) {\n    while (node && node.nodeType !== Node.ELEMENT_NODE) {\n      node = node.nextSibling;\n    }\n    return node;\n  }\n\n  function backwardsElement(node) {\n    while (node && node.nodeType !== Node.ELEMENT_NODE) {\n      node = node.previousSibling;\n    }\n    return node;\n  }\n\n  var ParentNodeInterface = {\n    get firstElementChild() {\n      return forwardElement(this.firstChild);\n    },\n\n    get lastElementChild() {\n      return backwardsElement(this.lastChild);\n    },\n\n    get childElementCount() {\n      var count = 0;\n      for (var child = this.firstElementChild;\n           child;\n           child = child.nextElementSibling) {\n        count++;\n      }\n      return count;\n    },\n\n    get children() {\n      var wrapperList = new NodeList();\n      var i = 0;\n      for (var child = this.firstElementChild;\n           child;\n           child = child.nextElementSibling) {\n        wrapperList[i++] = child;\n      }\n      wrapperList.length = i;\n      return wrapperList;\n    }\n  };\n\n  var ChildNodeInterface = {\n    get nextElementSibling() {\n      return forwardElement(this.nextSibling);\n    },\n\n    get previousElementSibling() {\n      return backwardsElement(this.previousSibling);\n    }\n  };\n\n  scope.ChildNodeInterface = ChildNodeInterface;\n  scope.ParentNodeInterface = ParentNodeInterface;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var ChildNodeInterface = scope.ChildNodeInterface;\n  var Node = scope.wrappers.Node;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalCharacterData = window.CharacterData;\n\n  function CharacterData(node) {\n    Node.call(this, node);\n  }\n  CharacterData.prototype = Object.create(Node.prototype);\n  mixin(CharacterData.prototype, {\n    get textContent() {\n      return this.data;\n    },\n    set textContent(value) {\n      this.data = value;\n    },\n    get data() {\n      return this.impl.data;\n    },\n    set data(value) {\n      var oldValue = this.impl.data;\n      enqueueMutation(this, 'characterData', {\n        oldValue: oldValue\n      });\n      this.impl.data = value;\n    }\n  });\n\n  mixin(CharacterData.prototype, ChildNodeInterface);\n\n  registerWrapper(OriginalCharacterData, CharacterData,\n                  document.createTextNode(''));\n\n  scope.wrappers.CharacterData = CharacterData;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var CharacterData = scope.wrappers.CharacterData;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  function toUInt32(x) {\n    return x >>> 0;\n  }\n\n  var OriginalText = window.Text;\n\n  function Text(node) {\n    CharacterData.call(this, node);\n  }\n  Text.prototype = Object.create(CharacterData.prototype);\n  mixin(Text.prototype, {\n    splitText: function(offset) {\n      offset = toUInt32(offset);\n      var s = this.data;\n      if (offset > s.length)\n        throw new Error('IndexSizeError');\n      var head = s.slice(0, offset);\n      var tail = s.slice(offset);\n      this.data = head;\n      var newTextNode = this.ownerDocument.createTextNode(tail);\n      if (this.parentNode)\n        this.parentNode.insertBefore(newTextNode, this.nextSibling);\n      return newTextNode;\n    }\n  });\n\n  registerWrapper(OriginalText, Text, document.createTextNode(''));\n\n  scope.wrappers.Text = Text;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var ChildNodeInterface = scope.ChildNodeInterface;\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var Node = scope.wrappers.Node;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var addWrapNodeListMethod = scope.addWrapNodeListMethod;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var oneOf = scope.oneOf;\n  var registerWrapper = scope.registerWrapper;\n  var wrappers = scope.wrappers;\n\n  var OriginalElement = window.Element;\n\n  var matchesNames = [\n    'matches',  // needs to come first.\n    'mozMatchesSelector',\n    'msMatchesSelector',\n    'webkitMatchesSelector',\n  ].filter(function(name) {\n    return OriginalElement.prototype[name];\n  });\n\n  var matchesName = matchesNames[0];\n\n  var originalMatches = OriginalElement.prototype[matchesName];\n\n  function invalidateRendererBasedOnAttribute(element, name) {\n    // Only invalidate if parent node is a shadow host.\n    var p = element.parentNode;\n    if (!p || !p.shadowRoot)\n      return;\n\n    var renderer = scope.getRendererForHost(p);\n    if (renderer.dependsOnAttribute(name))\n      renderer.invalidate();\n  }\n\n  function enqueAttributeChange(element, name, oldValue) {\n    // This is not fully spec compliant. We should use localName (which might\n    // have a different case than name) and the namespace (which requires us\n    // to get the Attr object).\n    enqueueMutation(element, 'attributes', {\n      name: name,\n      namespace: null,\n      oldValue: oldValue\n    });\n  }\n\n  function Element(node) {\n    Node.call(this, node);\n  }\n  Element.prototype = Object.create(Node.prototype);\n  mixin(Element.prototype, {\n    createShadowRoot: function() {\n      var newShadowRoot = new wrappers.ShadowRoot(this);\n      this.impl.polymerShadowRoot_ = newShadowRoot;\n\n      var renderer = scope.getRendererForHost(this);\n      renderer.invalidate();\n\n      return newShadowRoot;\n    },\n\n    get shadowRoot() {\n      return this.impl.polymerShadowRoot_ || null;\n    },\n\n    setAttribute: function(name, value) {\n      var oldValue = this.impl.getAttribute(name);\n      this.impl.setAttribute(name, value);\n      enqueAttributeChange(this, name, oldValue);\n      invalidateRendererBasedOnAttribute(this, name);\n    },\n\n    removeAttribute: function(name) {\n      var oldValue = this.impl.getAttribute(name);\n      this.impl.removeAttribute(name);\n      enqueAttributeChange(this, name, oldValue);\n      invalidateRendererBasedOnAttribute(this, name);\n    },\n\n    matches: function(selector) {\n      return originalMatches.call(this.impl, selector);\n    }\n  });\n\n  matchesNames.forEach(function(name) {\n    if (name !== 'matches') {\n      Element.prototype[name] = function(selector) {\n        return this.matches(selector);\n      };\n    }\n  });\n\n  if (OriginalElement.prototype.webkitCreateShadowRoot) {\n    Element.prototype.webkitCreateShadowRoot =\n        Element.prototype.createShadowRoot;\n  }\n\n  /**\n   * Useful for generating the accessor pair for a property that reflects an\n   * attribute.\n   */\n  function setterDirtiesAttribute(prototype, propertyName, opt_attrName) {\n    var attrName = opt_attrName || propertyName;\n    Object.defineProperty(prototype, propertyName, {\n      get: function() {\n        return this.impl[propertyName];\n      },\n      set: function(v) {\n        this.impl[propertyName] = v;\n        invalidateRendererBasedOnAttribute(this, attrName);\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  setterDirtiesAttribute(Element.prototype, 'id');\n  setterDirtiesAttribute(Element.prototype, 'className', 'class');\n\n  mixin(Element.prototype, ChildNodeInterface);\n  mixin(Element.prototype, GetElementsByInterface);\n  mixin(Element.prototype, ParentNodeInterface);\n  mixin(Element.prototype, SelectorsInterface);\n\n  registerWrapper(OriginalElement, Element,\n                  document.createElementNS(null, 'x'));\n\n  // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings\n  // that reflect attributes.\n  scope.matchesNames = matchesNames;\n  scope.wrappers.Element = Element;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var Element = scope.wrappers.Element;\n  var defineGetter = scope.defineGetter;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var nodesWereAdded = scope.nodesWereAdded;\n  var nodesWereRemoved = scope.nodesWereRemoved;\n  var registerWrapper = scope.registerWrapper;\n  var snapshotNodeList = scope.snapshotNodeList;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrappers = scope.wrappers;\n\n  /////////////////////////////////////////////////////////////////////////////\n  // innerHTML and outerHTML\n\n  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString\n  var escapeAttrRegExp = /[&\\u00A0\"]/g;\n  var escapeDataRegExp = /[&\\u00A0<>]/g;\n\n  function escapeReplace(c) {\n    switch (c) {\n      case '&':\n        return '&amp;';\n      case '<':\n        return '&lt;';\n      case '>':\n        return '&gt;';\n      case '\"':\n        return '&quot;'\n      case '\\u00A0':\n        return '&nbsp;';\n    }\n  }\n\n  function escapeAttr(s) {\n    return s.replace(escapeAttrRegExp, escapeReplace);\n  }\n\n  function escapeData(s) {\n    return s.replace(escapeDataRegExp, escapeReplace);\n  }\n\n  function makeSet(arr) {\n    var set = {};\n    for (var i = 0; i < arr.length; i++) {\n      set[arr[i]] = true;\n    }\n    return set;\n  }\n\n  // http://www.whatwg.org/specs/web-apps/current-work/#void-elements\n  var voidElements = makeSet([\n    'area',\n    'base',\n    'br',\n    'col',\n    'command',\n    'embed',\n    'hr',\n    'img',\n    'input',\n    'keygen',\n    'link',\n    'meta',\n    'param',\n    'source',\n    'track',\n    'wbr'\n  ]);\n\n  var plaintextParents = makeSet([\n    'style',\n    'script',\n    'xmp',\n    'iframe',\n    'noembed',\n    'noframes',\n    'plaintext',\n    'noscript'\n  ]);\n\n  function getOuterHTML(node, parentNode) {\n    switch (node.nodeType) {\n      case Node.ELEMENT_NODE:\n        var tagName = node.tagName.toLowerCase();\n        var s = '<' + tagName;\n        var attrs = node.attributes;\n        for (var i = 0, attr; attr = attrs[i]; i++) {\n          s += ' ' + attr.name + '=\"' + escapeAttr(attr.value) + '\"';\n        }\n        s += '>';\n        if (voidElements[tagName])\n          return s;\n\n        return s + getInnerHTML(node) + '</' + tagName + '>';\n\n      case Node.TEXT_NODE:\n        var data = node.data;\n        if (parentNode && plaintextParents[parentNode.localName])\n          return data;\n        return escapeData(data);\n\n      case Node.COMMENT_NODE:\n        return '<!--' + node.data + '-->';\n\n      default:\n        console.error(node);\n        throw new Error('not implemented');\n    }\n  }\n\n  function getInnerHTML(node) {\n    if (node instanceof wrappers.HTMLTemplateElement)\n      node = node.content;\n\n    var s = '';\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      s += getOuterHTML(child, node);\n    }\n    return s;\n  }\n\n  function setInnerHTML(node, value, opt_tagName) {\n    var tagName = opt_tagName || 'div';\n    node.textContent = '';\n    var tempElement = unwrap(node.ownerDocument.createElement(tagName));\n    tempElement.innerHTML = value;\n    var firstChild;\n    while (firstChild = tempElement.firstChild) {\n      node.appendChild(wrap(firstChild));\n    }\n  }\n\n  // IE11 does not have MSIE in the user agent string.\n  var oldIe = /MSIE/.test(navigator.userAgent);\n\n  var OriginalHTMLElement = window.HTMLElement;\n  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n\n  function HTMLElement(node) {\n    Element.call(this, node);\n  }\n  HTMLElement.prototype = Object.create(Element.prototype);\n  mixin(HTMLElement.prototype, {\n    get innerHTML() {\n      return getInnerHTML(this);\n    },\n    set innerHTML(value) {\n      // IE9 does not handle set innerHTML correctly on plaintextParents. It\n      // creates element children. For example\n      //\n      //   scriptElement.innerHTML = '<a>test</a>'\n      //\n      // Creates a single HTMLAnchorElement child.\n      if (oldIe && plaintextParents[this.localName]) {\n        this.textContent = value;\n        return;\n      }\n\n      var removedNodes = snapshotNodeList(this.childNodes);\n\n      if (this.invalidateShadowRenderer()) {\n        if (this instanceof wrappers.HTMLTemplateElement)\n          setInnerHTML(this.content, value);\n        else\n          setInnerHTML(this, value, this.tagName);\n\n      // If we have a non native template element we need to handle this\n      // manually since setting impl.innerHTML would add the html as direct\n      // children and not be moved over to the content fragment.\n      } else if (!OriginalHTMLTemplateElement &&\n                 this instanceof wrappers.HTMLTemplateElement) {\n        setInnerHTML(this.content, value);\n      } else {\n        this.impl.innerHTML = value;\n      }\n\n      var addedNodes = snapshotNodeList(this.childNodes);\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: addedNodes,\n        removedNodes: removedNodes\n      });\n\n      nodesWereRemoved(removedNodes);\n      nodesWereAdded(addedNodes, this);\n    },\n\n    get outerHTML() {\n      return getOuterHTML(this, this.parentNode);\n    },\n    set outerHTML(value) {\n      var p = this.parentNode;\n      if (p) {\n        p.invalidateShadowRenderer();\n        var df = frag(p, value);\n        p.replaceChild(df, this);\n      }\n    },\n\n    insertAdjacentHTML: function(position, text) {\n      var contextElement, refNode;\n      switch (String(position).toLowerCase()) {\n        case 'beforebegin':\n          contextElement = this.parentNode;\n          refNode = this;\n          break;\n        case 'afterend':\n          contextElement = this.parentNode;\n          refNode = this.nextSibling;\n          break;\n        case 'afterbegin':\n          contextElement = this;\n          refNode = this.firstChild;\n          break;\n        case 'beforeend':\n          contextElement = this;\n          refNode = null;\n          break;\n        default:\n          return;\n      }\n\n      var df = frag(contextElement, text);\n      contextElement.insertBefore(df, refNode);\n    }\n  });\n\n  function frag(contextElement, html) {\n    // TODO(arv): This does not work with SVG and other non HTML elements.\n    var p = unwrap(contextElement.cloneNode(false));\n    p.innerHTML = html;\n    var df = unwrap(document.createDocumentFragment());\n    var c;\n    while (c = p.firstChild) {\n      df.appendChild(c);\n    }\n    return wrap(df);\n  }\n\n  function getter(name) {\n    return function() {\n      scope.renderAllPending();\n      return this.impl[name];\n    };\n  }\n\n  function getterRequiresRendering(name) {\n    defineGetter(HTMLElement, name, getter(name));\n  }\n\n  [\n    'clientHeight',\n    'clientLeft',\n    'clientTop',\n    'clientWidth',\n    'offsetHeight',\n    'offsetLeft',\n    'offsetTop',\n    'offsetWidth',\n    'scrollHeight',\n    'scrollWidth',\n  ].forEach(getterRequiresRendering);\n\n  function getterAndSetterRequiresRendering(name) {\n    Object.defineProperty(HTMLElement.prototype, name, {\n      get: getter(name),\n      set: function(v) {\n        scope.renderAllPending();\n        this.impl[name] = v;\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  [\n    'scrollLeft',\n    'scrollTop',\n  ].forEach(getterAndSetterRequiresRendering);\n\n  function methodRequiresRendering(name) {\n    Object.defineProperty(HTMLElement.prototype, name, {\n      value: function() {\n        scope.renderAllPending();\n        return this.impl[name].apply(this.impl, arguments);\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  [\n    'getBoundingClientRect',\n    'getClientRects',\n    'scrollIntoView'\n  ].forEach(methodRequiresRendering);\n\n  // HTMLElement is abstract so we use a subclass that has no members.\n  registerWrapper(OriginalHTMLElement, HTMLElement,\n                  document.createElement('b'));\n\n  scope.wrappers.HTMLElement = HTMLElement;\n\n  // TODO: Find a better way to share these two with WrapperShadowRoot.\n  scope.getInnerHTML = getInnerHTML;\n  scope.setInnerHTML = setInnerHTML\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLCanvasElement = window.HTMLCanvasElement;\n\n  function HTMLCanvasElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);\n\n  mixin(HTMLCanvasElement.prototype, {\n    getContext: function() {\n      var context = this.impl.getContext.apply(this.impl, arguments);\n      return context && wrap(context);\n    }\n  });\n\n  registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement,\n                  document.createElement('canvas'));\n\n  scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLContentElement = window.HTMLContentElement;\n\n  function HTMLContentElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLContentElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLContentElement.prototype, {\n    get select() {\n      return this.getAttribute('select');\n    },\n    set select(value) {\n      this.setAttribute('select', value);\n    },\n\n    setAttribute: function(n, v) {\n      HTMLElement.prototype.setAttribute.call(this, n, v);\n      if (String(n).toLowerCase() === 'select')\n        this.invalidateShadowRenderer(true);\n    }\n\n    // getDistributedNodes is added in ShadowRenderer\n\n    // TODO: attribute boolean resetStyleInheritance;\n  });\n\n  if (OriginalHTMLContentElement)\n    registerWrapper(OriginalHTMLContentElement, HTMLContentElement);\n\n  scope.wrappers.HTMLContentElement = HTMLContentElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var rewrap = scope.rewrap;\n\n  var OriginalHTMLImageElement = window.HTMLImageElement;\n\n  function HTMLImageElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLImageElement.prototype = Object.create(HTMLElement.prototype);\n\n  registerWrapper(OriginalHTMLImageElement, HTMLImageElement,\n                  document.createElement('img'));\n\n  function Image(width, height) {\n    if (!(this instanceof Image)) {\n      throw new TypeError(\n          'DOM object constructor cannot be called as a function.');\n    }\n\n    var node = unwrap(document.createElement('img'));\n    HTMLElement.call(this, node);\n    rewrap(node, this);\n\n    if (width !== undefined)\n      node.width = width;\n    if (height !== undefined)\n      node.height = height;\n  }\n\n  Image.prototype = HTMLImageElement.prototype;\n\n  scope.wrappers.HTMLImageElement = HTMLImageElement;\n  scope.wrappers.Image = Image;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLShadowElement = window.HTMLShadowElement;\n\n  function HTMLShadowElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLShadowElement.prototype, {\n    // TODO: attribute boolean resetStyleInheritance;\n  });\n\n  if (OriginalHTMLShadowElement)\n    registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);\n\n  scope.wrappers.HTMLShadowElement = HTMLShadowElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var contentTable = new WeakMap();\n  var templateContentsOwnerTable = new WeakMap();\n\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner\n  function getTemplateContentsOwner(doc) {\n    if (!doc.defaultView)\n      return doc;\n    var d = templateContentsOwnerTable.get(doc);\n    if (!d) {\n      // TODO(arv): This should either be a Document or HTMLDocument depending\n      // on doc.\n      d = doc.implementation.createHTMLDocument('');\n      while (d.lastChild) {\n        d.removeChild(d.lastChild);\n      }\n      templateContentsOwnerTable.set(doc, d);\n    }\n    return d;\n  }\n\n  function extractContent(templateElement) {\n    // templateElement is not a wrapper here.\n    var doc = getTemplateContentsOwner(templateElement.ownerDocument);\n    var df = unwrap(doc.createDocumentFragment());\n    var child;\n    while (child = templateElement.firstChild) {\n      df.appendChild(child);\n    }\n    return df;\n  }\n\n  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n\n  function HTMLTemplateElement(node) {\n    HTMLElement.call(this, node);\n    if (!OriginalHTMLTemplateElement) {\n      var content = extractContent(node);\n      contentTable.set(this, wrap(content));\n    }\n  }\n  HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);\n\n  mixin(HTMLTemplateElement.prototype, {\n    get content() {\n      if (OriginalHTMLTemplateElement)\n        return wrap(this.impl.content);\n      return contentTable.get(this);\n    },\n\n    // TODO(arv): cloneNode needs to clone content.\n\n  });\n\n  if (OriginalHTMLTemplateElement)\n    registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);\n\n  scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLMediaElement = window.HTMLMediaElement;\n\n  function HTMLMediaElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);\n\n  registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement,\n                  document.createElement('audio'));\n\n  scope.wrappers.HTMLMediaElement = HTMLMediaElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLMediaElement = scope.wrappers.HTMLMediaElement;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var rewrap = scope.rewrap;\n\n  var OriginalHTMLAudioElement = window.HTMLAudioElement;\n\n  function HTMLAudioElement(node) {\n    HTMLMediaElement.call(this, node);\n  }\n  HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);\n\n  registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement,\n                  document.createElement('audio'));\n\n  function Audio(src) {\n    if (!(this instanceof Audio)) {\n      throw new TypeError(\n          'DOM object constructor cannot be called as a function.');\n    }\n\n    var node = unwrap(document.createElement('audio'));\n    HTMLMediaElement.call(this, node);\n    rewrap(node, this);\n\n    node.setAttribute('preload', 'auto');\n    if (src !== undefined)\n      node.setAttribute('src', src);\n  }\n\n  Audio.prototype = HTMLAudioElement.prototype;\n\n  scope.wrappers.HTMLAudioElement = HTMLAudioElement;\n  scope.wrappers.Audio = Audio;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var rewrap = scope.rewrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLOptionElement = window.HTMLOptionElement;\n\n  function trimText(s) {\n    return s.replace(/\\s+/g, ' ').trim();\n  }\n\n  function HTMLOptionElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLOptionElement.prototype, {\n    get text() {\n      return trimText(this.textContent);\n    },\n    set text(value) {\n      this.textContent = trimText(String(value));\n    },\n    get form() {\n      return wrap(unwrap(this).form);\n    }\n  });\n\n  registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement,\n                  document.createElement('option'));\n\n  function Option(text, value, defaultSelected, selected) {\n    if (!(this instanceof Option)) {\n      throw new TypeError(\n          'DOM object constructor cannot be called as a function.');\n    }\n\n    var node = unwrap(document.createElement('option'));\n    HTMLElement.call(this, node);\n    rewrap(node, this);\n\n    if (text !== undefined)\n      node.text = text;\n    if (value !== undefined)\n      node.setAttribute('value', value);\n    if (defaultSelected === true)\n      node.setAttribute('selected', '');\n    node.selected = selected === true;\n  }\n\n  Option.prototype = HTMLOptionElement.prototype;\n\n  scope.wrappers.HTMLOptionElement = HTMLOptionElement;\n  scope.wrappers.Option = Option;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLSelectElement = window.HTMLSelectElement;\n\n  function HTMLSelectElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLSelectElement.prototype, {\n    add: function(element, before) {\n      if (typeof before === 'object')  // also includes null\n        before = unwrap(before);\n      unwrap(this).add(unwrap(element), before);\n    },\n\n    remove: function(indexOrNode) {\n      // Spec only allows index but implementations allow index or node.\n      // remove() is also allowed which is same as remove(undefined)\n      if (typeof indexOrNode === 'object')\n        indexOrNode = unwrap(indexOrNode);\n      unwrap(this).remove(indexOrNode);\n    },\n\n    get form() {\n      return wrap(unwrap(this).form);\n    }\n  });\n\n  registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement,\n                  document.createElement('select'));\n\n  scope.wrappers.HTMLSelectElement = HTMLSelectElement;\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n\n  var OriginalHTMLTableElement = window.HTMLTableElement;\n\n  function HTMLTableElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableElement.prototype, {\n    get caption() {\n      return wrap(unwrap(this).caption);\n    },\n    createCaption: function() {\n      return wrap(unwrap(this).createCaption());\n    },\n\n    get tHead() {\n      return wrap(unwrap(this).tHead);\n    },\n    createTHead: function() {\n      return wrap(unwrap(this).createTHead());\n    },\n\n    createTFoot: function() {\n      return wrap(unwrap(this).createTFoot());\n    },\n    get tFoot() {\n      return wrap(unwrap(this).tFoot);\n    },\n\n    get tBodies() {\n      return wrapHTMLCollection(unwrap(this).tBodies);\n    },\n    createTBody: function() {\n      return wrap(unwrap(this).createTBody());\n    },\n\n    get rows() {\n      return wrapHTMLCollection(unwrap(this).rows);\n    },\n    insertRow: function(index) {\n      return wrap(unwrap(this).insertRow(index));\n    }\n  });\n\n  registerWrapper(OriginalHTMLTableElement, HTMLTableElement,\n                  document.createElement('table'));\n\n  scope.wrappers.HTMLTableElement = HTMLTableElement;\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;\n\n  function HTMLTableSectionElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableSectionElement.prototype, {\n    get rows() {\n      return wrapHTMLCollection(unwrap(this).rows);\n    },\n    insertRow: function(index) {\n      return wrap(unwrap(this).insertRow(index));\n    }\n  });\n\n  registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement,\n                  document.createElement('thead'));\n\n  scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLTableRowElement = window.HTMLTableRowElement;\n\n  function HTMLTableRowElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableRowElement.prototype, {\n    get cells() {\n      return wrapHTMLCollection(unwrap(this).cells);\n    },\n\n    insertCell: function(index) {\n      return wrap(unwrap(this).insertCell(index));\n    }\n  });\n\n  registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement,\n                  document.createElement('tr'));\n\n  scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLContentElement = scope.wrappers.HTMLContentElement;\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n  var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLUnknownElement = window.HTMLUnknownElement;\n\n  function HTMLUnknownElement(node) {\n    switch (node.localName) {\n      case 'content':\n        return new HTMLContentElement(node);\n      case 'shadow':\n        return new HTMLShadowElement(node);\n      case 'template':\n        return new HTMLTemplateElement(node);\n    }\n    HTMLElement.call(this, node);\n  }\n  HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);\n  registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);\n  scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var registerObject = scope.registerObject;\n\n  var SVG_NS = 'http://www.w3.org/2000/svg';\n  var svgTitleElement = document.createElementNS(SVG_NS, 'title');\n  var SVGTitleElement = registerObject(svgTitleElement);\n  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;\n\n  scope.wrappers.SVGElement = SVGElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalSVGUseElement = window.SVGUseElement;\n\n  // IE uses SVGElement as parent interface, SVG2 (Blink & Gecko) uses\n  // SVGGraphicsElement. Use the <g> element to get the right prototype.\n\n  var SVG_NS = 'http://www.w3.org/2000/svg';\n  var gWrapper = wrap(document.createElementNS(SVG_NS, 'g'));\n  var useElement = document.createElementNS(SVG_NS, 'use');\n  var SVGGElement = gWrapper.constructor;\n  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);\n  var parentInterface = parentInterfacePrototype.constructor;\n\n  function SVGUseElement(impl) {\n    parentInterface.call(this, impl);\n  }\n\n  SVGUseElement.prototype = Object.create(parentInterfacePrototype);\n\n  // Firefox does not expose instanceRoot.\n  if ('instanceRoot' in useElement) {\n    mixin(SVGUseElement.prototype, {\n      get instanceRoot() {\n        return wrap(unwrap(this).instanceRoot);\n      },\n      get animatedInstanceRoot() {\n        return wrap(unwrap(this).animatedInstanceRoot);\n      },\n    });\n  }\n\n  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);\n\n  scope.wrappers.SVGUseElement = SVGUseElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var EventTarget = scope.wrappers.EventTarget;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrap = scope.wrap;\n\n  var OriginalSVGElementInstance = window.SVGElementInstance;\n  if (!OriginalSVGElementInstance)\n    return;\n\n  function SVGElementInstance(impl) {\n    EventTarget.call(this, impl);\n  }\n\n  SVGElementInstance.prototype = Object.create(EventTarget.prototype);\n  mixin(SVGElementInstance.prototype, {\n    /** @type {SVGElement} */\n    get correspondingElement() {\n      return wrap(this.impl.correspondingElement);\n    },\n\n    /** @type {SVGUseElement} */\n    get correspondingUseElement() {\n      return wrap(this.impl.correspondingUseElement);\n    },\n\n    /** @type {SVGElementInstance} */\n    get parentNode() {\n      return wrap(this.impl.parentNode);\n    },\n\n    /** @type {SVGElementInstanceList} */\n    get childNodes() {\n      throw new Error('Not implemented');\n    },\n\n    /** @type {SVGElementInstance} */\n    get firstChild() {\n      return wrap(this.impl.firstChild);\n    },\n\n    /** @type {SVGElementInstance} */\n    get lastChild() {\n      return wrap(this.impl.lastChild);\n    },\n\n    /** @type {SVGElementInstance} */\n    get previousSibling() {\n      return wrap(this.impl.previousSibling);\n    },\n\n    /** @type {SVGElementInstance} */\n    get nextSibling() {\n      return wrap(this.impl.nextSibling);\n    }\n  });\n\n  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);\n\n  scope.wrappers.SVGElementInstance = SVGElementInstance;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n\n  function CanvasRenderingContext2D(impl) {\n    this.impl = impl;\n  }\n\n  mixin(CanvasRenderingContext2D.prototype, {\n    get canvas() {\n      return wrap(this.impl.canvas);\n    },\n\n    drawImage: function() {\n      arguments[0] = unwrapIfNeeded(arguments[0]);\n      this.impl.drawImage.apply(this.impl, arguments);\n    },\n\n    createPattern: function() {\n      arguments[0] = unwrap(arguments[0]);\n      return this.impl.createPattern.apply(this.impl, arguments);\n    }\n  });\n\n  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D,\n                  document.createElement('canvas').getContext('2d'));\n\n  scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n\n  // IE10 does not have WebGL.\n  if (!OriginalWebGLRenderingContext)\n    return;\n\n  function WebGLRenderingContext(impl) {\n    this.impl = impl;\n  }\n\n  mixin(WebGLRenderingContext.prototype, {\n    get canvas() {\n      return wrap(this.impl.canvas);\n    },\n\n    texImage2D: function() {\n      arguments[5] = unwrapIfNeeded(arguments[5]);\n      this.impl.texImage2D.apply(this.impl, arguments);\n    },\n\n    texSubImage2D: function() {\n      arguments[6] = unwrapIfNeeded(arguments[6]);\n      this.impl.texSubImage2D.apply(this.impl, arguments);\n    }\n  });\n\n  // Blink/WebKit has broken DOM bindings. Usually we would create an instance\n  // of the object and pass it into registerWrapper as a \"blueprint\" but\n  // creating WebGL contexts is expensive and might fail so we use a dummy\n  // object with dummy instance properties for these broken browsers.\n  var instanceProperties = /WebKit/.test(navigator.userAgent) ?\n      {drawingBufferHeight: null, drawingBufferWidth: null} : {};\n\n  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext,\n      instanceProperties);\n\n  scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalRange = window.Range;\n\n  function Range(impl) {\n    this.impl = impl;\n  }\n  Range.prototype = {\n    get startContainer() {\n      return wrap(this.impl.startContainer);\n    },\n    get endContainer() {\n      return wrap(this.impl.endContainer);\n    },\n    get commonAncestorContainer() {\n      return wrap(this.impl.commonAncestorContainer);\n    },\n    setStart: function(refNode,offset) {\n      this.impl.setStart(unwrapIfNeeded(refNode), offset);\n    },\n    setEnd: function(refNode,offset) {\n      this.impl.setEnd(unwrapIfNeeded(refNode), offset);\n    },\n    setStartBefore: function(refNode) {\n      this.impl.setStartBefore(unwrapIfNeeded(refNode));\n    },\n    setStartAfter: function(refNode) {\n      this.impl.setStartAfter(unwrapIfNeeded(refNode));\n    },\n    setEndBefore: function(refNode) {\n      this.impl.setEndBefore(unwrapIfNeeded(refNode));\n    },\n    setEndAfter: function(refNode) {\n      this.impl.setEndAfter(unwrapIfNeeded(refNode));\n    },\n    selectNode: function(refNode) {\n      this.impl.selectNode(unwrapIfNeeded(refNode));\n    },\n    selectNodeContents: function(refNode) {\n      this.impl.selectNodeContents(unwrapIfNeeded(refNode));\n    },\n    compareBoundaryPoints: function(how, sourceRange) {\n      return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));\n    },\n    extractContents: function() {\n      return wrap(this.impl.extractContents());\n    },\n    cloneContents: function() {\n      return wrap(this.impl.cloneContents());\n    },\n    insertNode: function(node) {\n      this.impl.insertNode(unwrapIfNeeded(node));\n    },\n    surroundContents: function(newParent) {\n      this.impl.surroundContents(unwrapIfNeeded(newParent));\n    },\n    cloneRange: function() {\n      return wrap(this.impl.cloneRange());\n    },\n    isPointInRange: function(node, offset) {\n      return this.impl.isPointInRange(unwrapIfNeeded(node), offset);\n    },\n    comparePoint: function(node, offset) {\n      return this.impl.comparePoint(unwrapIfNeeded(node), offset);\n    },\n    intersectsNode: function(node) {\n      return this.impl.intersectsNode(unwrapIfNeeded(node));\n    },\n    toString: function() {\n      return this.impl.toString();\n    }\n  };\n\n  // IE9 does not have createContextualFragment.\n  if (OriginalRange.prototype.createContextualFragment) {\n    Range.prototype.createContextualFragment = function(html) {\n      return wrap(this.impl.createContextualFragment(html));\n    };\n  }\n\n  registerWrapper(window.Range, Range, document.createRange());\n\n  scope.wrappers.Range = Range;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var mixin = scope.mixin;\n  var registerObject = scope.registerObject;\n\n  var DocumentFragment = registerObject(document.createDocumentFragment());\n  mixin(DocumentFragment.prototype, ParentNodeInterface);\n  mixin(DocumentFragment.prototype, SelectorsInterface);\n  mixin(DocumentFragment.prototype, GetElementsByInterface);\n\n  var Comment = registerObject(document.createComment(''));\n\n  scope.wrappers.Comment = Comment;\n  scope.wrappers.DocumentFragment = DocumentFragment;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var DocumentFragment = scope.wrappers.DocumentFragment;\n  var TreeScope = scope.TreeScope;\n  var elementFromPoint = scope.elementFromPoint;\n  var getInnerHTML = scope.getInnerHTML;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var rewrap = scope.rewrap;\n  var setInnerHTML = scope.setInnerHTML;\n  var unwrap = scope.unwrap;\n\n  var shadowHostTable = new WeakMap();\n  var nextOlderShadowTreeTable = new WeakMap();\n\n  var spaceCharRe = /[ \\t\\n\\r\\f]/;\n\n  function ShadowRoot(hostWrapper) {\n    var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());\n    DocumentFragment.call(this, node);\n\n    // createDocumentFragment associates the node with a wrapper\n    // DocumentFragment instance. Override that.\n    rewrap(node, this);\n\n    this.treeScope_ = new TreeScope(this, getTreeScope(hostWrapper));\n\n    var oldShadowRoot = hostWrapper.shadowRoot;\n    nextOlderShadowTreeTable.set(this, oldShadowRoot);\n\n    shadowHostTable.set(this, hostWrapper);\n  }\n  ShadowRoot.prototype = Object.create(DocumentFragment.prototype);\n  mixin(ShadowRoot.prototype, {\n    get innerHTML() {\n      return getInnerHTML(this);\n    },\n    set innerHTML(value) {\n      setInnerHTML(this, value);\n      this.invalidateShadowRenderer();\n    },\n\n    get olderShadowRoot() {\n      return nextOlderShadowTreeTable.get(this) || null;\n    },\n\n    get host() {\n      return shadowHostTable.get(this) || null;\n    },\n\n    invalidateShadowRenderer: function() {\n      return shadowHostTable.get(this).invalidateShadowRenderer();\n    },\n\n    elementFromPoint: function(x, y) {\n      return elementFromPoint(this, this.ownerDocument, x, y);\n    },\n\n    getElementById: function(id) {\n      if (spaceCharRe.test(id))\n        return null;\n      return this.querySelector('[id=\"' + id + '\"]');\n    }\n  });\n\n  scope.wrappers.ShadowRoot = ShadowRoot;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var Element = scope.wrappers.Element;\n  var HTMLContentElement = scope.wrappers.HTMLContentElement;\n  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n  var Node = scope.wrappers.Node;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  var assert = scope.assert;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var oneOf = scope.oneOf;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  /**\n   * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.\n   * Up means parentNode\n   * Sideways means previous and next sibling.\n   * @param {!Node} wrapper\n   */\n  function updateWrapperUpAndSideways(wrapper) {\n    wrapper.previousSibling_ = wrapper.previousSibling;\n    wrapper.nextSibling_ = wrapper.nextSibling;\n    wrapper.parentNode_ = wrapper.parentNode;\n  }\n\n  /**\n   * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.\n   * Down means first and last child\n   * @param {!Node} wrapper\n   */\n  function updateWrapperDown(wrapper) {\n    wrapper.firstChild_ = wrapper.firstChild;\n    wrapper.lastChild_ = wrapper.lastChild;\n  }\n\n  function updateAllChildNodes(parentNodeWrapper) {\n    assert(parentNodeWrapper instanceof Node);\n    for (var childWrapper = parentNodeWrapper.firstChild;\n         childWrapper;\n         childWrapper = childWrapper.nextSibling) {\n      updateWrapperUpAndSideways(childWrapper);\n    }\n    updateWrapperDown(parentNodeWrapper);\n  }\n\n  function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {\n    var parentNode = unwrap(parentNodeWrapper);\n    var newChild = unwrap(newChildWrapper);\n    var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;\n\n    remove(newChildWrapper);\n    updateWrapperUpAndSideways(newChildWrapper);\n\n    if (!refChildWrapper) {\n      parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;\n      if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild)\n        parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;\n\n      var lastChildWrapper = wrap(parentNode.lastChild);\n      if (lastChildWrapper)\n        lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;\n    } else {\n      if (parentNodeWrapper.firstChild === refChildWrapper)\n        parentNodeWrapper.firstChild_ = refChildWrapper;\n\n      refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;\n    }\n\n    parentNode.insertBefore(newChild, refChild);\n  }\n\n  function remove(nodeWrapper) {\n    var node = unwrap(nodeWrapper)\n    var parentNode = node.parentNode;\n    if (!parentNode)\n      return;\n\n    var parentNodeWrapper = wrap(parentNode);\n    updateWrapperUpAndSideways(nodeWrapper);\n\n    if (nodeWrapper.previousSibling)\n      nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;\n    if (nodeWrapper.nextSibling)\n      nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;\n\n    if (parentNodeWrapper.lastChild === nodeWrapper)\n      parentNodeWrapper.lastChild_ = nodeWrapper;\n    if (parentNodeWrapper.firstChild === nodeWrapper)\n      parentNodeWrapper.firstChild_ = nodeWrapper;\n\n    parentNode.removeChild(node);\n  }\n\n  var distributedChildNodesTable = new WeakMap();\n  var eventParentsTable = new WeakMap();\n  var insertionParentTable = new WeakMap();\n  var rendererForHostTable = new WeakMap();\n\n  function distributeChildToInsertionPoint(child, insertionPoint) {\n    getDistributedChildNodes(insertionPoint).push(child);\n    assignToInsertionPoint(child, insertionPoint);\n\n    var eventParents = eventParentsTable.get(child);\n    if (!eventParents)\n      eventParentsTable.set(child, eventParents = []);\n    eventParents.push(insertionPoint);\n  }\n\n  function resetDistributedChildNodes(insertionPoint) {\n    distributedChildNodesTable.set(insertionPoint, []);\n  }\n\n  function getDistributedChildNodes(insertionPoint) {\n    var rv = distributedChildNodesTable.get(insertionPoint);\n    if (!rv)\n      distributedChildNodesTable.set(insertionPoint, rv = []);\n    return rv;\n  }\n\n  function getChildNodesSnapshot(node) {\n    var result = [], i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      result[i++] = child;\n    }\n    return result;\n  }\n\n  /**\n   * Visits all nodes in the tree that fulfils the |predicate|. If the |visitor|\n   * function returns |false| the traversal is aborted.\n   * @param {!Node} tree\n   * @param {function(!Node) : boolean} predicate\n   * @param {function(!Node) : *} visitor\n   */\n  function visit(tree, predicate, visitor) {\n    // This operates on logical DOM.\n    for (var node = tree.firstChild; node; node = node.nextSibling) {\n      if (predicate(node)) {\n        if (visitor(node) === false)\n          return;\n      } else {\n        visit(node, predicate, visitor);\n      }\n    }\n  }\n\n  // Matching Insertion Points\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#matching-insertion-points\n\n  // TODO(arv): Verify this... I don't remember why I picked this regexp.\n  var selectorMatchRegExp = /^[*.:#[a-zA-Z_|]/;\n\n  var allowedPseudoRegExp = new RegExp('^:(' + [\n    'link',\n    'visited',\n    'target',\n    'enabled',\n    'disabled',\n    'checked',\n    'indeterminate',\n    'nth-child',\n    'nth-last-child',\n    'nth-of-type',\n    'nth-last-of-type',\n    'first-child',\n    'last-child',\n    'first-of-type',\n    'last-of-type',\n    'only-of-type',\n  ].join('|') + ')');\n\n\n  /**\n   * @param {Element} node\n   * @oaram {Element} point The insertion point element.\n   * @return {boolean} Whether the node matches the insertion point.\n   */\n  function matchesCriteria(node, point) {\n    var select = point.getAttribute('select');\n    if (!select)\n      return true;\n\n    // Here we know the select attribute is a non empty string.\n    select = select.trim();\n    if (!select)\n      return true;\n\n    if (!(node instanceof Element))\n      return false;\n\n    // The native matches function in IE9 does not correctly work with elements\n    // that are not in the document.\n    // TODO(arv): Implement matching in JS.\n    // https://github.com/Polymer/ShadowDOM/issues/361\n    if (select === '*' || select === node.localName)\n      return true;\n\n    // TODO(arv): This does not seem right. Need to check for a simple selector.\n    if (!selectorMatchRegExp.test(select))\n      return false;\n\n    // TODO(arv): This no longer matches the spec.\n    if (select[0] === ':' && !allowedPseudoRegExp.test(select))\n      return false;\n\n    try {\n      return node.matches(select);\n    } catch (ex) {\n      // Invalid selector.\n      return false;\n    }\n  }\n\n  var request = oneOf(window, [\n    'requestAnimationFrame',\n    'mozRequestAnimationFrame',\n    'webkitRequestAnimationFrame',\n    'setTimeout'\n  ]);\n\n  var pendingDirtyRenderers = [];\n  var renderTimer;\n\n  function renderAllPending() {\n    // TODO(arv): Order these in document order. That way we do not have to\n    // render something twice.\n    for (var i = 0; i < pendingDirtyRenderers.length; i++) {\n      var renderer = pendingDirtyRenderers[i];\n      var parentRenderer = renderer.parentRenderer;\n      if (parentRenderer && parentRenderer.dirty)\n        continue;\n      renderer.render();\n    }\n\n    pendingDirtyRenderers = [];\n  }\n\n  function handleRequestAnimationFrame() {\n    renderTimer = null;\n    renderAllPending();\n  }\n\n  /**\n   * Returns existing shadow renderer for a host or creates it if it is needed.\n   * @params {!Element} host\n   * @return {!ShadowRenderer}\n   */\n  function getRendererForHost(host) {\n    var renderer = rendererForHostTable.get(host);\n    if (!renderer) {\n      renderer = new ShadowRenderer(host);\n      rendererForHostTable.set(host, renderer);\n    }\n    return renderer;\n  }\n\n  function getShadowRootAncestor(node) {\n    var root = getTreeScope(node).root;\n    if (root instanceof ShadowRoot)\n      return root;\n    return null;\n  }\n\n  function getRendererForShadowRoot(shadowRoot) {\n    return getRendererForHost(shadowRoot.host);\n  }\n\n  var spliceDiff = new ArraySplice();\n  spliceDiff.equals = function(renderNode, rawNode) {\n    return unwrap(renderNode.node) === rawNode;\n  };\n\n  /**\n   * RenderNode is used as an in memory \"render tree\". When we render the\n   * composed tree we create a tree of RenderNodes, then we diff this against\n   * the real DOM tree and make minimal changes as needed.\n   */\n  function RenderNode(node) {\n    this.skip = false;\n    this.node = node;\n    this.childNodes = [];\n  }\n\n  RenderNode.prototype = {\n    append: function(node) {\n      var rv = new RenderNode(node);\n      this.childNodes.push(rv);\n      return rv;\n    },\n\n    sync: function(opt_added) {\n      if (this.skip)\n        return;\n\n      var nodeWrapper = this.node;\n      // plain array of RenderNodes\n      var newChildren = this.childNodes;\n      // plain array of real nodes.\n      var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));\n      var added = opt_added || new WeakMap();\n\n      var splices = spliceDiff.calculateSplices(newChildren, oldChildren);\n\n      var newIndex = 0, oldIndex = 0;\n      var lastIndex = 0;\n      for (var i = 0; i < splices.length; i++) {\n        var splice = splices[i];\n        for (; lastIndex < splice.index; lastIndex++) {\n          oldIndex++;\n          newChildren[newIndex++].sync(added);\n        }\n\n        var removedCount = splice.removed.length;\n        for (var j = 0; j < removedCount; j++) {\n          var wrapper = wrap(oldChildren[oldIndex++]);\n          if (!added.get(wrapper))\n            remove(wrapper);\n        }\n\n        var addedCount = splice.addedCount;\n        var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);\n        for (var j = 0; j < addedCount; j++) {\n          var newChildRenderNode = newChildren[newIndex++];\n          var newChildWrapper = newChildRenderNode.node;\n          insertBefore(nodeWrapper, newChildWrapper, refNode);\n\n          // Keep track of added so that we do not remove the node after it\n          // has been added.\n          added.set(newChildWrapper, true);\n\n          newChildRenderNode.sync(added);\n        }\n\n        lastIndex += addedCount;\n      }\n\n      for (var i = lastIndex; i < newChildren.length; i++) {\n        newChildren[i].sync(added);\n      }\n    }\n  };\n\n  function ShadowRenderer(host) {\n    this.host = host;\n    this.dirty = false;\n    this.invalidateAttributes();\n    this.associateNode(host);\n  }\n\n  ShadowRenderer.prototype = {\n\n    // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees\n    render: function(opt_renderNode) {\n      if (!this.dirty)\n        return;\n\n      this.invalidateAttributes();\n      this.treeComposition();\n\n      var host = this.host;\n      var shadowRoot = host.shadowRoot;\n\n      this.associateNode(host);\n      var topMostRenderer = !renderNode;\n      var renderNode = opt_renderNode || new RenderNode(host);\n\n      for (var node = shadowRoot.firstChild; node; node = node.nextSibling) {\n        this.renderNode(shadowRoot, renderNode, node, false);\n      }\n\n      if (topMostRenderer)\n        renderNode.sync();\n\n      this.dirty = false;\n    },\n\n    get parentRenderer() {\n      return getTreeScope(this.host).renderer;\n    },\n\n    invalidate: function() {\n      if (!this.dirty) {\n        this.dirty = true;\n        pendingDirtyRenderers.push(this);\n        if (renderTimer)\n          return;\n        renderTimer = window[request](handleRequestAnimationFrame, 0);\n      }\n    },\n\n    renderNode: function(shadowRoot, renderNode, node, isNested) {\n      if (isShadowHost(node)) {\n        renderNode = renderNode.append(node);\n        var renderer = getRendererForHost(node);\n        renderer.dirty = true;  // Need to rerender due to reprojection.\n        renderer.render(renderNode);\n      } else if (isInsertionPoint(node)) {\n        this.renderInsertionPoint(shadowRoot, renderNode, node, isNested);\n      } else if (isShadowInsertionPoint(node)) {\n        this.renderShadowInsertionPoint(shadowRoot, renderNode, node);\n      } else {\n        this.renderAsAnyDomTree(shadowRoot, renderNode, node, isNested);\n      }\n    },\n\n    renderAsAnyDomTree: function(shadowRoot, renderNode, node, isNested) {\n      renderNode = renderNode.append(node);\n\n      if (isShadowHost(node)) {\n        var renderer = getRendererForHost(node);\n        renderNode.skip = !renderer.dirty;\n        renderer.render(renderNode);\n      } else {\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          this.renderNode(shadowRoot, renderNode, child, isNested);\n        }\n      }\n    },\n\n    renderInsertionPoint: function(shadowRoot, renderNode, insertionPoint,\n                                   isNested) {\n      var distributedChildNodes = getDistributedChildNodes(insertionPoint);\n      if (distributedChildNodes.length) {\n        this.associateNode(insertionPoint);\n\n        for (var i = 0; i < distributedChildNodes.length; i++) {\n          var child = distributedChildNodes[i];\n          if (isInsertionPoint(child) && isNested)\n            this.renderInsertionPoint(shadowRoot, renderNode, child, isNested);\n          else\n            this.renderAsAnyDomTree(shadowRoot, renderNode, child, isNested);\n        }\n      } else {\n        this.renderFallbackContent(shadowRoot, renderNode, insertionPoint);\n      }\n      this.associateNode(insertionPoint.parentNode);\n    },\n\n    renderShadowInsertionPoint: function(shadowRoot, renderNode,\n                                         shadowInsertionPoint) {\n      var nextOlderTree = shadowRoot.olderShadowRoot;\n      if (nextOlderTree) {\n        assignToInsertionPoint(nextOlderTree, shadowInsertionPoint);\n        this.associateNode(shadowInsertionPoint.parentNode);\n        for (var node = nextOlderTree.firstChild;\n             node;\n             node = node.nextSibling) {\n          this.renderNode(nextOlderTree, renderNode, node, true);\n        }\n      } else {\n        this.renderFallbackContent(shadowRoot, renderNode,\n                                   shadowInsertionPoint);\n      }\n    },\n\n    renderFallbackContent: function(shadowRoot, renderNode, fallbackHost) {\n      this.associateNode(fallbackHost);\n      this.associateNode(fallbackHost.parentNode);\n      for (var node = fallbackHost.firstChild; node; node = node.nextSibling) {\n        this.renderAsAnyDomTree(shadowRoot, renderNode, node, false);\n      }\n    },\n\n    /**\n     * Invalidates the attributes used to keep track of which attributes may\n     * cause the renderer to be invalidated.\n     */\n    invalidateAttributes: function() {\n      this.attributes = Object.create(null);\n    },\n\n    /**\n     * Parses the selector and makes this renderer dependent on the attribute\n     * being used in the selector.\n     * @param {string} selector\n     */\n    updateDependentAttributes: function(selector) {\n      if (!selector)\n        return;\n\n      var attributes = this.attributes;\n\n      // .class\n      if (/\\.\\w+/.test(selector))\n        attributes['class'] = true;\n\n      // #id\n      if (/#\\w+/.test(selector))\n        attributes['id'] = true;\n\n      selector.replace(/\\[\\s*([^\\s=\\|~\\]]+)/g, function(_, name) {\n        attributes[name] = true;\n      });\n\n      // Pseudo selectors have been removed from the spec.\n    },\n\n    dependsOnAttribute: function(name) {\n      return this.attributes[name];\n    },\n\n    // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-distribution-algorithm\n    distribute: function(tree, pool) {\n      var self = this;\n\n      visit(tree, isActiveInsertionPoint,\n          function(insertionPoint) {\n            resetDistributedChildNodes(insertionPoint);\n            self.updateDependentAttributes(\n                insertionPoint.getAttribute('select'));\n\n            for (var i = 0; i < pool.length; i++) {  // 1.2\n              var node = pool[i];  // 1.2.1\n              if (node === undefined)  // removed\n                continue;\n              if (matchesCriteria(node, insertionPoint)) {  // 1.2.2\n                distributeChildToInsertionPoint(node, insertionPoint);  // 1.2.2.1\n                pool[i] = undefined;  // 1.2.2.2\n              }\n            }\n          });\n    },\n\n    // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-tree-composition\n    treeComposition: function () {\n      var shadowHost = this.host;\n      var tree = shadowHost.shadowRoot;  // 1.\n      var pool = [];  // 2.\n\n      for (var child = shadowHost.firstChild;\n           child;\n           child = child.nextSibling) {  // 3.\n        if (isInsertionPoint(child)) {  // 3.2.\n          var reprojected = getDistributedChildNodes(child);  // 3.2.1.\n          // if reprojected is undef... reset it?\n          if (!reprojected || !reprojected.length)  // 3.2.2.\n            reprojected = getChildNodesSnapshot(child);\n          pool.push.apply(pool, reprojected);  // 3.2.3.\n        } else {\n          pool.push(child); // 3.3.\n        }\n      }\n\n      var shadowInsertionPoint, point;\n      while (tree) {  // 4.\n        // 4.1.\n        shadowInsertionPoint = undefined;  // Reset every iteration.\n        visit(tree, isActiveShadowInsertionPoint, function(point) {\n          shadowInsertionPoint = point;\n          return false;\n        });\n        point = shadowInsertionPoint;\n\n        this.distribute(tree, pool);  // 4.2.\n        if (point) {  // 4.3.\n          var nextOlderTree = tree.olderShadowRoot;  // 4.3.1.\n          if (!nextOlderTree) {\n            break;  // 4.3.1.1.\n          } else {\n            tree = nextOlderTree;  // 4.3.2.2.\n            assignToInsertionPoint(tree, point);  // 4.3.2.2.\n            continue;  // 4.3.2.3.\n          }\n        } else {\n          break;  // 4.4.\n        }\n      }\n    },\n\n    associateNode: function(node) {\n      node.impl.polymerShadowRenderer_ = this;\n    }\n  };\n\n  function isInsertionPoint(node) {\n    // Should this include <shadow>?\n    return node instanceof HTMLContentElement;\n  }\n\n  function isActiveInsertionPoint(node) {\n    // <content> inside another <content> or <shadow> is considered inactive.\n    return node instanceof HTMLContentElement;\n  }\n\n  function isShadowInsertionPoint(node) {\n    return node instanceof HTMLShadowElement;\n  }\n\n  function isActiveShadowInsertionPoint(node) {\n    // <shadow> inside another <content> or <shadow> is considered inactive.\n    return node instanceof HTMLShadowElement;\n  }\n\n  function isShadowHost(shadowHost) {\n    return shadowHost.shadowRoot;\n  }\n\n  function getShadowTrees(host) {\n    var trees = [];\n\n    for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {\n      trees.push(tree);\n    }\n    return trees;\n  }\n\n  function assignToInsertionPoint(tree, point) {\n    insertionParentTable.set(tree, point);\n  }\n\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees\n  function render(host) {\n    new ShadowRenderer(host).render();\n  };\n\n  // Need to rerender shadow host when:\n  //\n  // - a direct child to the ShadowRoot is added or removed\n  // - a direct child to the host is added or removed\n  // - a new shadow root is created\n  // - a direct child to a content/shadow element is added or removed\n  // - a sibling to a content/shadow element is added or removed\n  // - content[select] is changed\n  // - an attribute in a direct child to a host is modified\n\n  /**\n   * This gets called when a node was added or removed to it.\n   */\n  Node.prototype.invalidateShadowRenderer = function(force) {\n    var renderer = this.impl.polymerShadowRenderer_;\n    if (renderer) {\n      renderer.invalidate();\n      return true;\n    }\n\n    return false;\n  };\n\n  HTMLContentElement.prototype.getDistributedNodes = function() {\n    // TODO(arv): We should only rerender the dirty ancestor renderers (from\n    // the root and down).\n    renderAllPending();\n    return getDistributedChildNodes(this);\n  };\n\n  HTMLShadowElement.prototype.nodeIsInserted_ =\n  HTMLContentElement.prototype.nodeIsInserted_ = function() {\n    // Invalidate old renderer if any.\n    this.invalidateShadowRenderer();\n\n    var shadowRoot = getShadowRootAncestor(this);\n    var renderer;\n    if (shadowRoot)\n      renderer = getRendererForShadowRoot(shadowRoot);\n    this.impl.polymerShadowRenderer_ = renderer;\n    if (renderer)\n      renderer.invalidate();\n  };\n\n  scope.eventParentsTable = eventParentsTable;\n  scope.getRendererForHost = getRendererForHost;\n  scope.getShadowTrees = getShadowTrees;\n  scope.insertionParentTable = insertionParentTable;\n  scope.renderAllPending = renderAllPending;\n\n  // Exposed for testing\n  scope.visual = {\n    insertBefore: insertBefore,\n    remove: remove,\n  };\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var assert = scope.assert;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var elementsWithFormProperty = [\n    'HTMLButtonElement',\n    'HTMLFieldSetElement',\n    'HTMLInputElement',\n    'HTMLKeygenElement',\n    'HTMLLabelElement',\n    'HTMLLegendElement',\n    'HTMLObjectElement',\n    // HTMLOptionElement is handled in HTMLOptionElement.js\n    'HTMLOutputElement',\n    // HTMLSelectElement is handled in HTMLSelectElement.js\n    'HTMLTextAreaElement',\n  ];\n\n  function createWrapperConstructor(name) {\n    if (!window[name])\n      return;\n\n    // Ensure we are not overriding an already existing constructor.\n    assert(!scope.wrappers[name]);\n\n    var GeneratedWrapper = function(node) {\n      // At this point all of them extend HTMLElement.\n      HTMLElement.call(this, node);\n    }\n    GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);\n    mixin(GeneratedWrapper.prototype, {\n      get form() {\n        return wrap(unwrap(this).form);\n      },\n    });\n\n    registerWrapper(window[name], GeneratedWrapper,\n        document.createElement(name.slice(4, -7)));\n    scope.wrappers[name] = GeneratedWrapper;\n  }\n\n  elementsWithFormProperty.forEach(createWrapperConstructor);\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalSelection = window.Selection;\n\n  function Selection(impl) {\n    this.impl = impl;\n  }\n  Selection.prototype = {\n    get anchorNode() {\n      return wrap(this.impl.anchorNode);\n    },\n    get focusNode() {\n      return wrap(this.impl.focusNode);\n    },\n    addRange: function(range) {\n      this.impl.addRange(unwrap(range));\n    },\n    collapse: function(node, index) {\n      this.impl.collapse(unwrapIfNeeded(node), index);\n    },\n    containsNode: function(node, allowPartial) {\n      return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);\n    },\n    extend: function(node, offset) {\n      this.impl.extend(unwrapIfNeeded(node), offset);\n    },\n    getRangeAt: function(index) {\n      return wrap(this.impl.getRangeAt(index));\n    },\n    removeRange: function(range) {\n      this.impl.removeRange(unwrap(range));\n    },\n    selectAllChildren: function(node) {\n      this.impl.selectAllChildren(unwrapIfNeeded(node));\n    },\n    toString: function() {\n      return this.impl.toString();\n    }\n  };\n\n  // WebKit extensions. Not implemented.\n  // readonly attribute Node baseNode;\n  // readonly attribute long baseOffset;\n  // readonly attribute Node extentNode;\n  // readonly attribute long extentOffset;\n  // [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,\n  //                       [Default=Undefined] optional long baseOffset,\n  //                       [Default=Undefined] optional Node extentNode,\n  //                       [Default=Undefined] optional long extentOffset);\n  // [RaisesException, ImplementedAs=collapse] void setPosition([Default=Undefined] optional Node node,\n  //                  [Default=Undefined] optional long offset);\n\n  registerWrapper(window.Selection, Selection, window.getSelection());\n\n  scope.wrappers.Selection = Selection;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var Node = scope.wrappers.Node;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var Selection = scope.wrappers.Selection;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  var TreeScope = scope.TreeScope;\n  var cloneNode = scope.cloneNode;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var elementFromPoint = scope.elementFromPoint;\n  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n  var matchesNames = scope.matchesNames;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var renderAllPending = scope.renderAllPending;\n  var rewrap = scope.rewrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapEventTargetMethods = scope.wrapEventTargetMethods;\n  var wrapNodeList = scope.wrapNodeList;\n\n  var implementationTable = new WeakMap();\n\n  function Document(node) {\n    Node.call(this, node);\n    this.treeScope_ = new TreeScope(this, null);\n  }\n  Document.prototype = Object.create(Node.prototype);\n\n  defineWrapGetter(Document, 'documentElement');\n\n  // Conceptually both body and head can be in a shadow but suporting that seems\n  // overkill at this point.\n  defineWrapGetter(Document, 'body');\n  defineWrapGetter(Document, 'head');\n\n  // document cannot be overridden so we override a bunch of its methods\n  // directly on the instance.\n\n  function wrapMethod(name) {\n    var original = document[name];\n    Document.prototype[name] = function() {\n      return wrap(original.apply(this.impl, arguments));\n    };\n  }\n\n  [\n    'createComment',\n    'createDocumentFragment',\n    'createElement',\n    'createElementNS',\n    'createEvent',\n    'createEventNS',\n    'createRange',\n    'createTextNode',\n    'getElementById'\n  ].forEach(wrapMethod);\n\n  var originalAdoptNode = document.adoptNode;\n\n  function adoptNodeNoRemove(node, doc) {\n    originalAdoptNode.call(doc.impl, unwrap(node));\n    adoptSubtree(node, doc);\n  }\n\n  function adoptSubtree(node, doc) {\n    if (node.shadowRoot)\n      doc.adoptNode(node.shadowRoot);\n    if (node instanceof ShadowRoot)\n      adoptOlderShadowRoots(node, doc);\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      adoptSubtree(child, doc);\n    }\n  }\n\n  function adoptOlderShadowRoots(shadowRoot, doc) {\n    var oldShadowRoot = shadowRoot.olderShadowRoot;\n    if (oldShadowRoot)\n      doc.adoptNode(oldShadowRoot);\n  }\n\n  var originalGetSelection = document.getSelection;\n\n  mixin(Document.prototype, {\n    adoptNode: function(node) {\n      if (node.parentNode)\n        node.parentNode.removeChild(node);\n      adoptNodeNoRemove(node, this);\n      return node;\n    },\n    elementFromPoint: function(x, y) {\n      return elementFromPoint(this, this, x, y);\n    },\n    importNode: function(node, deep) {\n      return cloneNode(node, deep, this.impl);\n    },\n    getSelection: function() {\n      renderAllPending();\n      return new Selection(originalGetSelection.call(unwrap(this)));\n    }\n  });\n\n  if (document.registerElement) {\n    var originalRegisterElement = document.registerElement;\n    Document.prototype.registerElement = function(tagName, object) {\n      var prototype = object.prototype;\n\n      // If we already used the object as a prototype for another custom\n      // element.\n      if (scope.nativePrototypeTable.get(prototype)) {\n        // TODO(arv): DOMException\n        throw new Error('NotSupportedError');\n      }\n\n      // Find first object on the prototype chain that already have a native\n      // prototype. Keep track of all the objects before that so we can create\n      // a similar structure for the native case.\n      var proto = Object.getPrototypeOf(prototype);\n      var nativePrototype;\n      var prototypes = [];\n      while (proto) {\n        nativePrototype = scope.nativePrototypeTable.get(proto);\n        if (nativePrototype)\n          break;\n        prototypes.push(proto);\n        proto = Object.getPrototypeOf(proto);\n      }\n\n      if (!nativePrototype) {\n        // TODO(arv): DOMException\n        throw new Error('NotSupportedError');\n      }\n\n      // This works by creating a new prototype object that is empty, but has\n      // the native prototype as its proto. The original prototype object\n      // passed into register is used as the wrapper prototype.\n\n      var newPrototype = Object.create(nativePrototype);\n      for (var i = prototypes.length - 1; i >= 0; i--) {\n        newPrototype = Object.create(newPrototype);\n      }\n\n      // Add callbacks if present.\n      // Names are taken from:\n      //   https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp&sq=package:chromium&type=cs&l=156\n      // and not from the spec since the spec is out of date.\n      [\n        'createdCallback',\n        'attachedCallback',\n        'detachedCallback',\n        'attributeChangedCallback',\n      ].forEach(function(name) {\n        var f = prototype[name];\n        if (!f)\n          return;\n        newPrototype[name] = function() {\n          // if this element has been wrapped prior to registration,\n          // the wrapper is stale; in this case rewrap\n          if (!(wrap(this) instanceof CustomElementConstructor)) {\n            rewrap(this);\n          }\n          f.apply(wrap(this), arguments);\n        };\n      });\n\n      var p = {prototype: newPrototype};\n      if (object.extends)\n        p.extends = object.extends;\n\n      function CustomElementConstructor(node) {\n        if (!node) {\n          if (object.extends) {\n            return document.createElement(object.extends, tagName);\n          } else {\n            return document.createElement(tagName);\n          }\n        }\n        this.impl = node;\n      }\n      CustomElementConstructor.prototype = prototype;\n      CustomElementConstructor.prototype.constructor = CustomElementConstructor;\n\n      scope.constructorTable.set(newPrototype, CustomElementConstructor);\n      scope.nativePrototypeTable.set(prototype, newPrototype);\n\n      // registration is synchronous so do it last\n      var nativeConstructor = originalRegisterElement.call(unwrap(this),\n          tagName, p);\n      return CustomElementConstructor;\n    };\n\n    forwardMethodsToWrapper([\n      window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n    ], [\n      'registerElement',\n    ]);\n  }\n\n  // We also override some of the methods on document.body and document.head\n  // for convenience.\n  forwardMethodsToWrapper([\n    window.HTMLBodyElement,\n    window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n    window.HTMLHeadElement,\n    window.HTMLHtmlElement,\n  ], [\n    'appendChild',\n    'compareDocumentPosition',\n    'contains',\n    'getElementsByClassName',\n    'getElementsByTagName',\n    'getElementsByTagNameNS',\n    'insertBefore',\n    'querySelector',\n    'querySelectorAll',\n    'removeChild',\n    'replaceChild',\n  ].concat(matchesNames));\n\n  forwardMethodsToWrapper([\n    window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n  ], [\n    'adoptNode',\n    'importNode',\n    'contains',\n    'createComment',\n    'createDocumentFragment',\n    'createElement',\n    'createElementNS',\n    'createEvent',\n    'createEventNS',\n    'createRange',\n    'createTextNode',\n    'elementFromPoint',\n    'getElementById',\n    'getSelection',\n  ]);\n\n  mixin(Document.prototype, GetElementsByInterface);\n  mixin(Document.prototype, ParentNodeInterface);\n  mixin(Document.prototype, SelectorsInterface);\n\n  mixin(Document.prototype, {\n    get implementation() {\n      var implementation = implementationTable.get(this);\n      if (implementation)\n        return implementation;\n      implementation =\n          new DOMImplementation(unwrap(this).implementation);\n      implementationTable.set(this, implementation);\n      return implementation;\n    }\n  });\n\n  registerWrapper(window.Document, Document,\n      document.implementation.createHTMLDocument(''));\n\n  // Both WebKit and Gecko uses HTMLDocument for document. HTML5/DOM only has\n  // one Document interface and IE implements the standard correctly.\n  if (window.HTMLDocument)\n    registerWrapper(window.HTMLDocument, Document);\n\n  wrapEventTargetMethods([\n    window.HTMLBodyElement,\n    window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n    window.HTMLHeadElement,\n  ]);\n\n  function DOMImplementation(impl) {\n    this.impl = impl;\n  }\n\n  function wrapImplMethod(constructor, name) {\n    var original = document.implementation[name];\n    constructor.prototype[name] = function() {\n      return wrap(original.apply(this.impl, arguments));\n    };\n  }\n\n  function forwardImplMethod(constructor, name) {\n    var original = document.implementation[name];\n    constructor.prototype[name] = function() {\n      return original.apply(this.impl, arguments);\n    };\n  }\n\n  wrapImplMethod(DOMImplementation, 'createDocumentType');\n  wrapImplMethod(DOMImplementation, 'createDocument');\n  wrapImplMethod(DOMImplementation, 'createHTMLDocument');\n  forwardImplMethod(DOMImplementation, 'hasFeature');\n\n  registerWrapper(window.DOMImplementation, DOMImplementation);\n\n  forwardMethodsToWrapper([\n    window.DOMImplementation,\n  ], [\n    'createDocumentType',\n    'createDocument',\n    'createHTMLDocument',\n    'hasFeature',\n  ]);\n\n  scope.adoptNodeNoRemove = adoptNodeNoRemove;\n  scope.wrappers.DOMImplementation = DOMImplementation;\n  scope.wrappers.Document = Document;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var EventTarget = scope.wrappers.EventTarget;\n  var Selection = scope.wrappers.Selection;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var renderAllPending = scope.renderAllPending;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalWindow = window.Window;\n  var originalGetComputedStyle = window.getComputedStyle;\n  var originalGetSelection = window.getSelection;\n\n  function Window(impl) {\n    EventTarget.call(this, impl);\n  }\n  Window.prototype = Object.create(EventTarget.prototype);\n\n  OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {\n    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);\n  };\n\n  OriginalWindow.prototype.getSelection = function() {\n    return wrap(this || window).getSelection();\n  };\n\n  // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065\n  delete window.getComputedStyle;\n  delete window.getSelection;\n\n  ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(\n      function(name) {\n        OriginalWindow.prototype[name] = function() {\n          var w = wrap(this || window);\n          return w[name].apply(w, arguments);\n        };\n\n        // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065\n        delete window[name];\n      });\n\n  mixin(Window.prototype, {\n    getComputedStyle: function(el, pseudo) {\n      renderAllPending();\n      return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),\n                                           pseudo);\n    },\n    getSelection: function() {\n      renderAllPending();\n      return new Selection(originalGetSelection.call(unwrap(this)));\n    },\n  });\n\n  registerWrapper(OriginalWindow, Window);\n\n  scope.wrappers.Window = Window;\n\n})(window.ShadowDOMPolyfill);\n","/**\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var unwrap = scope.unwrap;\n\n  // DataTransfer (Clipboard in old Blink/WebKit) has a single method that\n  // requires wrapping. Since it is only a method we do not need a real wrapper,\n  // we can just override the method.\n\n  var OriginalDataTransfer = window.DataTransfer || window.Clipboard;\n  var OriginalDataTransferSetDragImage =\n      OriginalDataTransfer.prototype.setDragImage;\n\n  OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {\n    OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);\n  };\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var isWrapperFor = scope.isWrapperFor;\n\n  // This is a list of the elements we currently override the global constructor\n  // for.\n  var elements = {\n    'a': 'HTMLAnchorElement',\n    // Do not create an applet element by default since it shows a warning in\n    // IE.\n    // https://github.com/Polymer/polymer/issues/217\n    // 'applet': 'HTMLAppletElement',\n    'area': 'HTMLAreaElement',\n    'audio': 'HTMLAudioElement',\n    'base': 'HTMLBaseElement',\n    'body': 'HTMLBodyElement',\n    'br': 'HTMLBRElement',\n    'button': 'HTMLButtonElement',\n    'canvas': 'HTMLCanvasElement',\n    'caption': 'HTMLTableCaptionElement',\n    'col': 'HTMLTableColElement',\n    // 'command': 'HTMLCommandElement',  // Not fully implemented in Gecko.\n    'content': 'HTMLContentElement',\n    'data': 'HTMLDataElement',\n    'datalist': 'HTMLDataListElement',\n    'del': 'HTMLModElement',\n    'dir': 'HTMLDirectoryElement',\n    'div': 'HTMLDivElement',\n    'dl': 'HTMLDListElement',\n    'embed': 'HTMLEmbedElement',\n    'fieldset': 'HTMLFieldSetElement',\n    'font': 'HTMLFontElement',\n    'form': 'HTMLFormElement',\n    'frame': 'HTMLFrameElement',\n    'frameset': 'HTMLFrameSetElement',\n    'h1': 'HTMLHeadingElement',\n    'head': 'HTMLHeadElement',\n    'hr': 'HTMLHRElement',\n    'html': 'HTMLHtmlElement',\n    'iframe': 'HTMLIFrameElement',\n    'img': 'HTMLImageElement',\n    'input': 'HTMLInputElement',\n    'keygen': 'HTMLKeygenElement',\n    'label': 'HTMLLabelElement',\n    'legend': 'HTMLLegendElement',\n    'li': 'HTMLLIElement',\n    'link': 'HTMLLinkElement',\n    'map': 'HTMLMapElement',\n    'marquee': 'HTMLMarqueeElement',\n    'menu': 'HTMLMenuElement',\n    'menuitem': 'HTMLMenuItemElement',\n    'meta': 'HTMLMetaElement',\n    'meter': 'HTMLMeterElement',\n    'object': 'HTMLObjectElement',\n    'ol': 'HTMLOListElement',\n    'optgroup': 'HTMLOptGroupElement',\n    'option': 'HTMLOptionElement',\n    'output': 'HTMLOutputElement',\n    'p': 'HTMLParagraphElement',\n    'param': 'HTMLParamElement',\n    'pre': 'HTMLPreElement',\n    'progress': 'HTMLProgressElement',\n    'q': 'HTMLQuoteElement',\n    'script': 'HTMLScriptElement',\n    'select': 'HTMLSelectElement',\n    'shadow': 'HTMLShadowElement',\n    'source': 'HTMLSourceElement',\n    'span': 'HTMLSpanElement',\n    'style': 'HTMLStyleElement',\n    'table': 'HTMLTableElement',\n    'tbody': 'HTMLTableSectionElement',\n    // WebKit and Moz are wrong:\n    // https://bugs.webkit.org/show_bug.cgi?id=111469\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=848096\n    // 'td': 'HTMLTableCellElement',\n    'template': 'HTMLTemplateElement',\n    'textarea': 'HTMLTextAreaElement',\n    'thead': 'HTMLTableSectionElement',\n    'time': 'HTMLTimeElement',\n    'title': 'HTMLTitleElement',\n    'tr': 'HTMLTableRowElement',\n    'track': 'HTMLTrackElement',\n    'ul': 'HTMLUListElement',\n    'video': 'HTMLVideoElement',\n  };\n\n  function overrideConstructor(tagName) {\n    var nativeConstructorName = elements[tagName];\n    var nativeConstructor = window[nativeConstructorName];\n    if (!nativeConstructor)\n      return;\n    var element = document.createElement(tagName);\n    var wrapperConstructor = element.constructor;\n    window[nativeConstructorName] = wrapperConstructor;\n  }\n\n  Object.keys(elements).forEach(overrideConstructor);\n\n  Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {\n    window[name] = scope.wrappers[name]\n  });\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n\n  // convenient global\n  window.wrap = ShadowDOMPolyfill.wrapIfNeeded;\n  window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;\n\n  // users may want to customize other types\n  // TODO(sjmiles): 'button' is now supported by ShadowDOMPolyfill, but\n  // I've left this code here in case we need to temporarily patch another\n  // type\n  /*\n  (function() {\n    var elts = {HTMLButtonElement: 'button'};\n    for (var c in elts) {\n      window[c] = function() { throw 'Patched Constructor'; };\n      window[c].prototype = Object.getPrototypeOf(\n          document.createElement(elts[c]));\n    }\n  })();\n  */\n\n  // patch in prefixed name\n  Object.defineProperty(Element.prototype, 'webkitShadowRoot',\n      Object.getOwnPropertyDescriptor(Element.prototype, 'shadowRoot'));\n\n  var originalCreateShadowRoot = Element.prototype.createShadowRoot;\n  Element.prototype.createShadowRoot = function() {\n    var root = originalCreateShadowRoot.call(this);\n    CustomElements.watchShadow(this);\n    return root;\n  };\n\n  Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;\n})();\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/*\n  This is a limited shim for ShadowDOM css styling.\n  https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles\n  \n  The intention here is to support only the styling features which can be \n  relatively simply implemented. The goal is to allow users to avoid the \n  most obvious pitfalls and do so without compromising performance significantly. \n  For ShadowDOM styling that's not covered here, a set of best practices\n  can be provided that should allow users to accomplish more complex styling.\n\n  The following is a list of specific ShadowDOM styling features and a brief\n  discussion of the approach used to shim.\n\n  Shimmed features:\n\n  * :host, :ancestor: ShadowDOM allows styling of the shadowRoot's host\n  element using the :host rule. To shim this feature, the :host styles are \n  reformatted and prefixed with a given scope name and promoted to a \n  document level stylesheet.\n  For example, given a scope name of .foo, a rule like this:\n  \n    :host {\n        background: red;\n      }\n    }\n  \n  becomes:\n  \n    .foo {\n      background: red;\n    }\n  \n  * encapsultion: Styles defined within ShadowDOM, apply only to \n  dom inside the ShadowDOM. Polymer uses one of two techniques to imlement\n  this feature.\n  \n  By default, rules are prefixed with the host element tag name \n  as a descendant selector. This ensures styling does not leak out of the 'top'\n  of the element's ShadowDOM. For example,\n\n  div {\n      font-weight: bold;\n    }\n  \n  becomes:\n\n  x-foo div {\n      font-weight: bold;\n    }\n  \n  becomes:\n\n\n  Alternatively, if Platform.ShadowCSS.strictStyling is set to true then \n  selectors are scoped by adding an attribute selector suffix to each\n  simple selector that contains the host element tag name. Each element \n  in the element's ShadowDOM template is also given the scope attribute. \n  Thus, these rules match only elements that have the scope attribute.\n  For example, given a scope name of x-foo, a rule like this:\n  \n    div {\n      font-weight: bold;\n    }\n  \n  becomes:\n  \n    div[x-foo] {\n      font-weight: bold;\n    }\n\n  Note that elements that are dynamically added to a scope must have the scope\n  selector added to them manually.\n\n  * upper/lower bound encapsulation: Styles which are defined outside a\n  shadowRoot should not cross the ShadowDOM boundary and should not apply\n  inside a shadowRoot.\n\n  This styling behavior is not emulated. Some possible ways to do this that \n  were rejected due to complexity and/or performance concerns include: (1) reset\n  every possible property for every possible selector for a given scope name;\n  (2) re-implement css in javascript.\n  \n  As an alternative, users should make sure to use selectors\n  specific to the scope in which they are working.\n  \n  * ::distributed: This behavior is not emulated. It's often not necessary\n  to style the contents of a specific insertion point and instead, descendants\n  of the host element can be styled selectively. Users can also create an \n  extra node around an insertion point and style that node's contents\n  via descendent selectors. For example, with a shadowRoot like this:\n  \n    <style>\n      ::content(div) {\n        background: red;\n      }\n    </style>\n    <content></content>\n  \n  could become:\n  \n    <style>\n      / *@polyfill .content-container div * / \n      ::content(div) {\n        background: red;\n      }\n    </style>\n    <div class=\"content-container\">\n      <content></content>\n    </div>\n  \n  Note the use of @polyfill in the comment above a ShadowDOM specific style\n  declaration. This is a directive to the styling shim to use the selector \n  in comments in lieu of the next selector when running under polyfill.\n*/\n(function(scope) {\n\nvar ShadowCSS = {\n  strictStyling: false,\n  registry: {},\n  // Shim styles for a given root associated with a name and extendsName\n  // 1. cache root styles by name\n  // 2. optionally tag root nodes with scope name\n  // 3. shim polyfill directives /* @polyfill */ and /* @polyfill-rule */\n  // 4. shim :host and scoping\n  shimStyling: function(root, name, extendsName) {\n    var scopeStyles = this.prepareRoot(root, name, extendsName);\n    var typeExtension = this.isTypeExtension(extendsName);\n    var scopeSelector = this.makeScopeSelector(name, typeExtension);\n    // use caching to make working with styles nodes easier and to facilitate\n    // lookup of extendee\n    var cssText = stylesToCssText(scopeStyles, true);\n    cssText = this.scopeCssText(cssText, scopeSelector);\n    // cache shimmed css on root for user extensibility\n    if (root) {\n      root.shimmedStyle = cssText;\n    }\n    // add style to document\n    this.addCssToDocument(cssText, name);\n  },\n  /*\n  * Shim a style element with the given selector. Returns cssText that can\n  * be included in the document via Platform.ShadowCSS.addCssToDocument(css).\n  */\n  shimStyle: function(style, selector) {\n    return this.shimCssText(style.textContent, selector);\n  },\n  /*\n  * Shim some cssText with the given selector. Returns cssText that can\n  * be included in the document via Platform.ShadowCSS.addCssToDocument(css).\n  */\n  shimCssText: function(cssText, selector) {\n    cssText = this.insertDirectives(cssText);\n    return this.scopeCssText(cssText, selector);\n  },\n  makeScopeSelector: function(name, typeExtension) {\n    if (name) {\n      return typeExtension ? '[is=' + name + ']' : name;\n    }\n    return '';\n  },\n  isTypeExtension: function(extendsName) {\n    return extendsName && extendsName.indexOf('-') < 0;\n  },\n  prepareRoot: function(root, name, extendsName) {\n    var def = this.registerRoot(root, name, extendsName);\n    this.replaceTextInStyles(def.rootStyles, this.insertDirectives);\n    // remove existing style elements\n    this.removeStyles(root, def.rootStyles);\n    // apply strict attr\n    if (this.strictStyling) {\n      this.applyScopeToContent(root, name);\n    }\n    return def.scopeStyles;\n  },\n  removeStyles: function(root, styles) {\n    for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {\n      s.parentNode.removeChild(s);\n    }\n  },\n  registerRoot: function(root, name, extendsName) {\n    var def = this.registry[name] = {\n      root: root,\n      name: name,\n      extendsName: extendsName\n    }\n    var styles = this.findStyles(root);\n    def.rootStyles = styles;\n    def.scopeStyles = def.rootStyles;\n    var extendee = this.registry[def.extendsName];\n    if (extendee && (!root || root.querySelector('shadow'))) {\n      def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);\n    }\n    return def;\n  },\n  findStyles: function(root) {\n    if (!root) {\n      return [];\n    }\n    var styles = root.querySelectorAll('style');\n    return Array.prototype.filter.call(styles, function(s) {\n      return !s.hasAttribute(NO_SHIM_ATTRIBUTE);\n    });\n  },\n  applyScopeToContent: function(root, name) {\n    if (root) {\n      // add the name attribute to each node in root.\n      Array.prototype.forEach.call(root.querySelectorAll('*'),\n          function(node) {\n            node.setAttribute(name, '');\n          });\n      // and template contents too\n      Array.prototype.forEach.call(root.querySelectorAll('template'),\n          function(template) {\n            this.applyScopeToContent(template.content, name);\n          },\n          this);\n    }\n  },\n  insertDirectives: function(cssText) {\n    cssText = this.insertPolyfillDirectivesInCssText(cssText);\n    return this.insertPolyfillRulesInCssText(cssText);\n  },\n  /*\n   * Process styles to convert native ShadowDOM rules that will trip\n   * up the css parser; we rely on decorating the stylesheet with inert rules.\n   * \n   * For example, we convert this rule:\n   * \n   * polyfill-next-selector { content: ':host menu-item'; }\n   * ::content menu-item {\n   * \n   * to this:\n   * \n   * scopeName menu-item {\n   *\n  **/\n  insertPolyfillDirectivesInCssText: function(cssText) {\n    // TODO(sorvell): remove either content or comment\n    cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {\n      // remove end comment delimiter and add block start\n      return p1.slice(0, -2) + '{';\n    });\n    return cssText.replace(cssContentNextSelectorRe, function(match, p1) {\n      return p1 + ' {';\n    });\n  },\n  /*\n   * Process styles to add rules which will only apply under the polyfill\n   * \n   * For example, we convert this rule:\n   * \n   * polyfill-rule {\n   *   content: ':host menu-item';\n   * ...\n   * }\n   * \n   * to this:\n   * \n   * scopeName menu-item {...}\n   *\n  **/\n  insertPolyfillRulesInCssText: function(cssText) {\n    // TODO(sorvell): remove either content or comment\n    cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {\n      // remove end comment delimiter\n      return p1.slice(0, -1);\n    });\n    return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {\n      var rule = match.replace(p1, '').replace(p2, '');\n      return p3 + rule;\n    });\n  },\n  /* Ensure styles are scoped. Pseudo-scoping takes a rule like:\n   * \n   *  .foo {... } \n   *  \n   *  and converts this to\n   *  \n   *  scopeName .foo { ... }\n  */\n  scopeCssText: function(cssText, scopeSelector) {\n    var unscoped = this.extractUnscopedRulesFromCssText(cssText);\n    cssText = this.insertPolyfillHostInCssText(cssText);\n    cssText = this.convertColonHost(cssText);\n    cssText = this.convertColonAncestor(cssText);\n    cssText = this.convertCombinators(cssText);\n    if (scopeSelector) {\n      var self = this, cssText;\n      withCssRules(cssText, function(rules) {\n        cssText = self.scopeRules(rules, scopeSelector);\n      });\n\n    }\n    cssText = cssText + '\\n' + unscoped;\n    return cssText.trim();\n  },\n  /*\n   * Process styles to add rules which will only apply under the polyfill\n   * and do not process via CSSOM. (CSSOM is destructive to rules on rare \n   * occasions, e.g. -webkit-calc on Safari.)\n   * For example, we convert this rule:\n   * \n   * (comment start) @polyfill-unscoped-rule menu-item { \n   * ... } (comment end)\n   * \n   * to this:\n   * \n   * menu-item {...}\n   *\n  **/\n  extractUnscopedRulesFromCssText: function(cssText) {\n    // TODO(sorvell): remove either content or comment\n    var r = '', m;\n    while (m = cssCommentUnscopedRuleRe.exec(cssText)) {\n      r += m[1].slice(0, -1) + '\\n\\n';\n    }\n    while (m = cssContentUnscopedRuleRe.exec(cssText)) {\n      r += m[0].replace(m[2], '').replace(m[1], m[3]) + '\\n\\n';\n    }\n    return r;\n  },\n  /*\n   * convert a rule like :host(.foo) > .bar { }\n   *\n   * to\n   *\n   * scopeName.foo > .bar\n  */\n  convertColonHost: function(cssText) {\n    return this.convertColonRule(cssText, cssColonHostRe,\n        this.colonHostPartReplacer);\n  },\n  /*\n   * convert a rule like :ancestor(.foo) > .bar { }\n   *\n   * to\n   *\n   * scopeName.foo > .bar, .foo scopeName > .bar { }\n   * \n   * and\n   *\n   * :ancestor(.foo:host) .bar { ... }\n   * \n   * to\n   * \n   * scopeName.foo .bar { ... }\n  */\n  convertColonAncestor: function(cssText) {\n    return this.convertColonRule(cssText, cssColonAncestorRe,\n        this.colonAncestorPartReplacer);\n  },\n  convertColonRule: function(cssText, regExp, partReplacer) {\n    // p1 = :host, p2 = contents of (), p3 rest of rule\n    return cssText.replace(regExp, function(m, p1, p2, p3) {\n      p1 = polyfillHostNoCombinator;\n      if (p2) {\n        var parts = p2.split(','), r = [];\n        for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {\n          p = p.trim();\n          r.push(partReplacer(p1, p, p3));\n        }\n        return r.join(',');\n      } else {\n        return p1 + p3;\n      }\n    });\n  },\n  colonAncestorPartReplacer: function(host, part, suffix) {\n    if (part.match(polyfillHost)) {\n      return this.colonHostPartReplacer(host, part, suffix);\n    } else {\n      return host + part + suffix + ', ' + part + ' ' + host + suffix;\n    }\n  },\n  colonHostPartReplacer: function(host, part, suffix) {\n    return host + part.replace(polyfillHost, '') + suffix;\n  },\n  /*\n   * Convert ^ and ^^ combinators by replacing with space.\n  */\n  convertCombinators: function(cssText) {\n    for (var i=0; i < combinatorsRe.length; i++) {\n      cssText = cssText.replace(combinatorsRe[i], ' ');\n    }\n    return cssText;\n  },\n  // change a selector like 'div' to 'name div'\n  scopeRules: function(cssRules, scopeSelector) {\n    var cssText = '';\n    if (cssRules) {\n      Array.prototype.forEach.call(cssRules, function(rule) {\n        if (rule.selectorText && (rule.style && rule.style.cssText)) {\n          cssText += this.scopeSelector(rule.selectorText, scopeSelector, \n            this.strictStyling) + ' {\\n\\t';\n          cssText += this.propertiesFromRule(rule) + '\\n}\\n\\n';\n        } else if (rule.type === CSSRule.MEDIA_RULE) {\n          cssText += '@media ' + rule.media.mediaText + ' {\\n';\n          cssText += this.scopeRules(rule.cssRules, scopeSelector);\n          cssText += '\\n}\\n\\n';\n        } else if (rule.cssText) {\n          cssText += rule.cssText + '\\n\\n';\n        }\n      }, this);\n    }\n    return cssText;\n  },\n  scopeSelector: function(selector, scopeSelector, strict) {\n    var r = [], parts = selector.split(',');\n    parts.forEach(function(p) {\n      p = p.trim();\n      if (this.selectorNeedsScoping(p, scopeSelector)) {\n        p = (strict && !p.match(polyfillHostNoCombinator)) ? \n            this.applyStrictSelectorScope(p, scopeSelector) :\n            this.applySimpleSelectorScope(p, scopeSelector);\n      }\n      r.push(p);\n    }, this);\n    return r.join(', ');\n  },\n  selectorNeedsScoping: function(selector, scopeSelector) {\n    var re = this.makeScopeMatcher(scopeSelector);\n    return !selector.match(re);\n  },\n  makeScopeMatcher: function(scopeSelector) {\n    scopeSelector = scopeSelector.replace(/\\[/g, '\\\\[').replace(/\\[/g, '\\\\]');\n    return new RegExp('^(' + scopeSelector + ')' + selectorReSuffix, 'm');\n  },\n  // scope via name and [is=name]\n  applySimpleSelectorScope: function(selector, scopeSelector) {\n    if (selector.match(polyfillHostRe)) {\n      selector = selector.replace(polyfillHostNoCombinator, scopeSelector);\n      return selector.replace(polyfillHostRe, scopeSelector + ' ');\n    } else {\n      return scopeSelector + ' ' + selector;\n    }\n  },\n  // return a selector with [name] suffix on each simple selector\n  // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]\n  applyStrictSelectorScope: function(selector, scopeSelector) {\n    scopeSelector = scopeSelector.replace(/\\[is=([^\\]]*)\\]/g, '$1');\n    var splits = [' ', '>', '+', '~'],\n      scoped = selector,\n      attrName = '[' + scopeSelector + ']';\n    splits.forEach(function(sep) {\n      var parts = scoped.split(sep);\n      scoped = parts.map(function(p) {\n        // remove :host since it should be unnecessary\n        var t = p.trim().replace(polyfillHostRe, '');\n        if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {\n          p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3')\n        }\n        return p;\n      }).join(sep);\n    });\n    return scoped;\n  },\n  insertPolyfillHostInCssText: function(selector) {\n    return selector.replace(hostRe, polyfillHost).replace(colonHostRe,\n        polyfillHost).replace(colonAncestorRe, polyfillAncestor);\n  },\n  propertiesFromRule: function(rule) {\n    // TODO(sorvell): Safari cssom incorrectly removes quotes from the content\n    // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)\n    if (rule.style.content && !rule.style.content.match(/['\"]+/)) {\n      return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \\'' + \n          rule.style.content + '\\';');\n    }\n    return rule.style.cssText;\n  },\n  replaceTextInStyles: function(styles, action) {\n    if (styles && action) {\n      if (!(styles instanceof Array)) {\n        styles = [styles];\n      }\n      Array.prototype.forEach.call(styles, function(s) {\n        s.textContent = action.call(this, s.textContent);\n      }, this);\n    }\n  },\n  addCssToDocument: function(cssText, name) {\n    if (cssText.match('@import')) {\n      addOwnSheet(cssText, name);\n    } else {\n      addCssToDocument(cssText);\n    }\n  }\n};\n\nvar selectorRe = /([^{]*)({[\\s\\S]*?})/gim,\n    cssCommentRe = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//gim,\n    // TODO(sorvell): remove either content or comment\n    cssCommentNextSelectorRe = /\\/\\*\\s*@polyfill ([^*]*\\*+([^/*][^*]*\\*+)*\\/)([^{]*?){/gim,\n    cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\\:[\\s]*'([^']*)'[^}]*}([^{]*?){/gim,\n    // TODO(sorvell): remove either content or comment\n    cssCommentRuleRe = /\\/\\*\\s@polyfill-rule([^*]*\\*+([^/*][^*]*\\*+)*)\\//gim,\n    cssContentRuleRe = /(polyfill-rule)[^}]*(content\\:[\\s]*'([^']*)'[^;]*;)[^}]*}/gim,\n    // TODO(sorvell): remove either content or comment\n    cssCommentUnscopedRuleRe = /\\/\\*\\s@polyfill-unscoped-rule([^*]*\\*+([^/*][^*]*\\*+)*)\\//gim,\n    cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\\:[\\s]*'([^']*)'[^;]*;)[^}]*}/gim,\n    cssPseudoRe = /::(x-[^\\s{,(]*)/gim,\n    cssPartRe = /::part\\(([^)]*)\\)/gim,\n    // note: :host pre-processed to -shadowcsshost.\n    polyfillHost = '-shadowcsshost',\n    // note: :ancestor pre-processed to -shadowcssancestor.\n    polyfillAncestor = '-shadowcssancestor',\n    parenSuffix = ')(?:\\\\((' +\n        '(?:\\\\([^)(]*\\\\)|[^)(]*)+?' +\n        ')\\\\))?([^,{]*)';\n    cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),\n    cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim'),\n    selectorReSuffix = '([>\\\\s~+\\[.,{:][\\\\s\\\\S]*)?$',\n    hostRe = /@host/gim,\n    colonHostRe = /\\:host/gim,\n    colonAncestorRe = /\\:ancestor/gim,\n    /* host name without combinator */\n    polyfillHostNoCombinator = polyfillHost + '-no-combinator',\n    polyfillHostRe = new RegExp(polyfillHost, 'gim'),\n    polyfillAncestorRe = new RegExp(polyfillAncestor, 'gim'),\n    combinatorsRe = [\n      /\\^\\^/g,\n      /\\^/g,\n      /\\/shadow\\//g,\n      /\\/shadow-deep\\//g\n    ];\n\nfunction stylesToCssText(styles, preserveComments) {\n  var cssText = '';\n  Array.prototype.forEach.call(styles, function(s) {\n    cssText += s.textContent + '\\n\\n';\n  });\n  // strip comments for easier processing\n  if (!preserveComments) {\n    cssText = cssText.replace(cssCommentRe, '');\n  }\n  return cssText;\n}\n\nfunction cssTextToStyle(cssText) {\n  var style = document.createElement('style');\n  style.textContent = cssText;\n  return style;\n}\n\nfunction cssToRules(cssText) {\n  var style = cssTextToStyle(cssText);\n  document.head.appendChild(style);\n  var rules = [];\n  if (style.sheet) {\n    // TODO(sorvell): Firefox throws when accessing the rules of a stylesheet\n    // with an @import\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=625013\n    try {\n      rules = style.sheet.cssRules;\n    } catch(e) {\n      //\n    }\n  } else {\n    console.warn('sheet not found', style);\n  }\n  style.parentNode.removeChild(style);\n  return rules;\n}\n\nvar frame = document.createElement('iframe');\nframe.style.display = 'none';\n\nfunction initFrame() {\n  frame.initialized = true;\n  document.body.appendChild(frame);\n  var doc = frame.contentDocument;\n  var base = doc.createElement('base');\n  base.href = document.baseURI;\n  doc.head.appendChild(base);\n}\n\nfunction inFrame(fn) {\n  if (!frame.initialized) {\n    initFrame();\n  }\n  document.body.appendChild(frame);\n  fn(frame.contentDocument);\n  document.body.removeChild(frame);\n}\n\n// TODO(sorvell): use an iframe if the cssText contains an @import to workaround\n// https://code.google.com/p/chromium/issues/detail?id=345114\nvar isChrome = navigator.userAgent.match('Chrome');\nfunction withCssRules(cssText, callback) {\n  if (!callback) {\n    return;\n  }\n  var rules;\n  if (cssText.match('@import') && isChrome) {\n    var style = cssTextToStyle(cssText);\n    inFrame(function(doc) {\n      doc.head.appendChild(style.impl);\n      rules = style.sheet.cssRules;\n      callback(rules);\n    });\n  } else {\n    rules = cssToRules(cssText);\n    callback(rules);\n  }\n}\n\nfunction rulesToCss(cssRules) {\n  for (var i=0, css=[]; i < cssRules.length; i++) {\n    css.push(cssRules[i].cssText);\n  }\n  return css.join('\\n\\n');\n}\n\nfunction addCssToDocument(cssText) {\n  if (cssText) {\n    getSheet().appendChild(document.createTextNode(cssText));\n  }\n}\n\nfunction addOwnSheet(cssText, name) {\n  var style = cssTextToStyle(cssText);\n  style.setAttribute(name, '');\n  style.setAttribute(SHIMMED_ATTRIBUTE, '');\n  document.head.appendChild(style);\n}\n\nvar SHIM_ATTRIBUTE = 'shim-shadowdom';\nvar SHIMMED_ATTRIBUTE = 'shim-shadowdom-css';\nvar NO_SHIM_ATTRIBUTE = 'no-shim';\n\nvar sheet;\nfunction getSheet() {\n  if (!sheet) {\n    sheet = document.createElement(\"style\");\n    sheet.setAttribute(SHIMMED_ATTRIBUTE, '');\n    sheet[SHIMMED_ATTRIBUTE] = true;\n  }\n  return sheet;\n}\n\n// add polyfill stylesheet to document\nif (window.ShadowDOMPolyfill) {\n  addCssToDocument('style { display: none !important; }\\n');\n  var doc = wrap(document);\n  var head = doc.querySelector('head');\n  head.insertBefore(getSheet(), head.childNodes[0]);\n\n  // TODO(sorvell): monkey-patching HTMLImports is abusive;\n  // consider a better solution.\n  document.addEventListener('DOMContentLoaded', function() {\n    var urlResolver = scope.urlResolver;\n    \n    if (window.HTMLImports && !HTMLImports.useNative) {\n      var SHIM_SHEET_SELECTOR = 'link[rel=stylesheet]' +\n          '[' + SHIM_ATTRIBUTE + ']';\n      var SHIM_STYLE_SELECTOR = 'style[' + SHIM_ATTRIBUTE + ']';\n      HTMLImports.importer.documentPreloadSelectors += ',' + SHIM_SHEET_SELECTOR;\n      HTMLImports.importer.importsPreloadSelectors += ',' + SHIM_SHEET_SELECTOR;\n\n      HTMLImports.parser.documentSelectors = [\n        HTMLImports.parser.documentSelectors,\n        SHIM_SHEET_SELECTOR,\n        SHIM_STYLE_SELECTOR\n      ].join(',');\n  \n      var originalParseGeneric = HTMLImports.parser.parseGeneric;\n\n      HTMLImports.parser.parseGeneric = function(elt) {\n        if (elt[SHIMMED_ATTRIBUTE]) {\n          return;\n        }\n        var style = elt.__importElement || elt;\n        if (!style.hasAttribute(SHIM_ATTRIBUTE)) {\n          originalParseGeneric.call(this, elt);\n          return;\n        }\n        if (elt.__resource) {\n          style = elt.ownerDocument.createElement('style');\n          style.textContent = urlResolver.resolveCssText(\n              elt.__resource, elt.href);\n        } else {\n          urlResolver.resolveStyle(style);  \n        }\n        style.textContent = ShadowCSS.shimStyle(style);\n        style.removeAttribute(SHIM_ATTRIBUTE, '');\n        style.setAttribute(SHIMMED_ATTRIBUTE, '');\n        style[SHIMMED_ATTRIBUTE] = true;\n        // place in document\n        if (style.parentNode !== head) {\n          // replace links in head\n          if (elt.parentNode === head) {\n            head.replaceChild(style, elt);\n          } else {\n            head.appendChild(style);\n          }\n        }\n        style.__importParsed = true;\n        this.markParsingComplete(elt);\n      }\n\n      var hasResource = HTMLImports.parser.hasResource;\n      HTMLImports.parser.hasResource = function(node) {\n        if (node.localName === 'link' && node.rel === 'stylesheet' &&\n            node.hasAttribute(SHIM_ATTRIBUTE)) {\n          return (node.__resource);\n        } else {\n          return hasResource.call(this, node);\n        }\n      }\n\n    }\n  });\n}\n\n// exports\nscope.ShadowCSS = ShadowCSS;\n\n})(window.Platform);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n\n  // poor man's adapter for template.content on various platform scenarios\n  window.templateContent = window.templateContent || function(inTemplate) {\n    return inTemplate.content;\n  };\n\n  // so we can call wrap/unwrap without testing for ShadowDOMPolyfill\n\n  window.wrap = window.unwrap = function(n){\n    return n;\n  }\n\n  var originalCreateShadowRoot = Element.prototype.webkitCreateShadowRoot;\n  Element.prototype.webkitCreateShadowRoot = function() {\n    var elderRoot = this.webkitShadowRoot;\n    var root = originalCreateShadowRoot.call(this);\n    root.olderShadowRoot = elderRoot;\n    root.host = this;\n    CustomElements.watchShadow(this);\n    return root;\n  }\n\n  Object.defineProperties(Element.prototype, {\n    shadowRoot: {\n      get: function() {\n        return this.webkitShadowRoot;\n      }\n    },\n    createShadowRoot: {\n      value: function() {\n        return this.webkitCreateShadowRoot();\n      }\n    }\n  });\n\n  window.templateContent = function(inTemplate) {\n    // if MDV exists, it may need to boostrap this template to reveal content\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(inTemplate);\n    }\n    // fallback when there is no Shadow DOM polyfill, no MDV polyfill, and no\n    // native template support\n    if (!inTemplate.content && !inTemplate._content) {\n      var frag = document.createDocumentFragment();\n      while (inTemplate.firstChild) {\n        frag.appendChild(inTemplate.firstChild);\n      }\n      inTemplate._content = frag;\n    }\n    return inTemplate.content || inTemplate._content;\n  };\n\n})();","/* Any copyright is dedicated to the Public Domain.\n * http://creativecommons.org/publicdomain/zero/1.0/ */\n\n(function(scope) {\n  'use strict';\n\n  // feature detect for URL constructor\n  var hasWorkingUrl = false;\n  if (!scope.forceJURL) {\n    try {\n      var u = new URL('b', 'http://a');\n      hasWorkingUrl = u.href === 'http://a/b';\n    } catch(e) {}\n  }\n\n  if (hasWorkingUrl)\n    return;\n\n  var relative = Object.create(null);\n  relative['ftp'] = 21;\n  relative['file'] = 0;\n  relative['gopher'] = 70;\n  relative['http'] = 80;\n  relative['https'] = 443;\n  relative['ws'] = 80;\n  relative['wss'] = 443;\n\n  var relativePathDotMapping = Object.create(null);\n  relativePathDotMapping['%2e'] = '.';\n  relativePathDotMapping['.%2e'] = '..';\n  relativePathDotMapping['%2e.'] = '..';\n  relativePathDotMapping['%2e%2e'] = '..';\n\n  function isRelativeScheme(scheme) {\n    return relative[scheme] !== undefined;\n  }\n\n  function invalid() {\n    clear.call(this);\n    this._isInvalid = true;\n  }\n\n  function IDNAToASCII(h) {\n    if ('' == h) {\n      invalid.call(this)\n    }\n    // XXX\n    return h.toLowerCase()\n  }\n\n  function percentEscape(c) {\n    var unicode = c.charCodeAt(0);\n    if (unicode > 0x20 &&\n       unicode < 0x7F &&\n       // \" # < > ? `\n       [0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) == -1\n      ) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n\n  function percentEscapeQuery(c) {\n    // XXX This actually needs to encode c using encoding and then\n    // convert the bytes one-by-one.\n\n    var unicode = c.charCodeAt(0);\n    if (unicode > 0x20 &&\n       unicode < 0x7F &&\n       // \" # < > ` (do not escape '?')\n       [0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) == -1\n      ) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n\n  var EOF = undefined,\n      ALPHA = /[a-zA-Z]/,\n      ALPHANUMERIC = /[a-zA-Z0-9\\+\\-\\.]/;\n\n  function parse(input, stateOverride, base) {\n    function err(message) {\n      errors.push(message)\n    }\n\n    var state = stateOverride || 'scheme start',\n        cursor = 0,\n        buffer = '',\n        seenAt = false,\n        seenBracket = false,\n        errors = [];\n\n    loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {\n      var c = input[cursor];\n      switch (state) {\n        case 'scheme start':\n          if (c && ALPHA.test(c)) {\n            buffer += c.toLowerCase(); // ASCII-safe\n            state = 'scheme';\n          } else if (!stateOverride) {\n            buffer = '';\n            state = 'no scheme';\n            continue;\n          } else {\n            err('Invalid scheme.');\n            break loop;\n          }\n          break;\n\n        case 'scheme':\n          if (c && ALPHANUMERIC.test(c)) {\n            buffer += c.toLowerCase(); // ASCII-safe\n          } else if (':' == c) {\n            this._scheme = buffer;\n            buffer = '';\n            if (stateOverride) {\n              break loop;\n            }\n            if (isRelativeScheme(this._scheme)) {\n              this._isRelative = true;\n            }\n            if ('file' == this._scheme) {\n              state = 'relative';\n            } else if (this._isRelative && base && base._scheme == this._scheme) {\n              state = 'relative or authority';\n            } else if (this._isRelative) {\n              state = 'authority first slash';\n            } else {\n              state = 'scheme data';\n            }\n          } else if (!stateOverride) {\n            buffer = '';\n            cursor = 0;\n            state = 'no scheme';\n            continue;\n          } else if (EOF == c) {\n            break loop;\n          } else {\n            err('Code point not allowed in scheme: ' + c)\n            break loop;\n          }\n          break;\n\n        case 'scheme data':\n          if ('?' == c) {\n            query = '?';\n            state = 'query';\n          } else if ('#' == c) {\n            this._fragment = '#';\n            state = 'fragment';\n          } else {\n            // XXX error handling\n            if (EOF != c && '\\t' != c && '\\n' != c && '\\r' != c) {\n              this._schemeData += percentEscape(c);\n            }\n          }\n          break;\n\n        case 'no scheme':\n          if (!base || !(isRelativeScheme(base._scheme))) {\n            err('Missing scheme.');\n            invalid.call(this);\n          } else {\n            state = 'relative';\n            continue;\n          }\n          break;\n\n        case 'relative or authority':\n          if ('/' == c && '/' == input[cursor+1]) {\n            state = 'authority ignore slashes';\n          } else {\n            err('Expected /, got: ' + c);\n            state = 'relative';\n            continue\n          }\n          break;\n\n        case 'relative':\n          this._isRelative = true;\n          if ('file' != this._scheme)\n            this._scheme = base._scheme;\n          if (EOF == c) {\n            this._host = base._host;\n            this._port = base._port;\n            this._path = base._path.slice();\n            this._query = base._query;\n            break loop;\n          } else if ('/' == c || '\\\\' == c) {\n            if ('\\\\' == c)\n              err('\\\\ is an invalid code point.');\n            state = 'relative slash';\n          } else if ('?' == c) {\n            this._host = base._host;\n            this._port = base._port;\n            this._path = base._path.slice();\n            this._query = '?';\n            state = 'query';\n          } else if ('#' == c) {\n            this._host = base._host;\n            this._port = base._port;\n            this._path = base._path.slice();\n            this._query = base._query;\n            this._fragment = '#';\n            state = 'fragment';\n          } else {\n            var nextC = input[cursor+1]\n            var nextNextC = input[cursor+2]\n            if (\n              'file' != this._scheme || !ALPHA.test(c) ||\n              (nextC != ':' && nextC != '|') ||\n              (EOF != nextNextC && '/' != nextNextC && '\\\\' != nextNextC && '?' != nextNextC && '#' != nextNextC)) {\n              this._host = base._host;\n              this._port = base._port;\n              this._path = base._path.slice();\n              this._path.pop();\n            }\n            state = 'relative path';\n            continue;\n          }\n          break;\n\n        case 'relative slash':\n          if ('/' == c || '\\\\' == c) {\n            if ('\\\\' == c) {\n              err('\\\\ is an invalid code point.');\n            }\n            if ('file' == this._scheme) {\n              state = 'file host';\n            } else {\n              state = 'authority ignore slashes';\n            }\n          } else {\n            if ('file' != this._scheme) {\n              this._host = base._host;\n              this._port = base._port;\n            }\n            state = 'relative path';\n            continue;\n          }\n          break;\n\n        case 'authority first slash':\n          if ('/' == c) {\n            state = 'authority second slash';\n          } else {\n            err(\"Expected '/', got: \" + c);\n            state = 'authority ignore slashes';\n            continue;\n          }\n          break;\n\n        case 'authority second slash':\n          state = 'authority ignore slashes';\n          if ('/' != c) {\n            err(\"Expected '/', got: \" + c);\n            continue;\n          }\n          break;\n\n        case 'authority ignore slashes':\n          if ('/' != c && '\\\\' != c) {\n            state = 'authority';\n            continue;\n          } else {\n            err('Expected authority, got: ' + c);\n          }\n          break;\n\n        case 'authority':\n          if ('@' == c) {\n            if (seenAt) {\n              err('@ already seen.');\n              buffer += '%40';\n            }\n            seenAt = true;\n            for (var i = 0; i < buffer.length; i++) {\n              var cp = buffer[i];\n              if ('\\t' == cp || '\\n' == cp || '\\r' == cp) {\n                err('Invalid whitespace in authority.');\n                continue;\n              }\n              // XXX check URL code points\n              if (':' == cp && null === this._password) {\n                this._password = '';\n                continue;\n              }\n              var tempC = percentEscape(cp);\n              (null !== this._password) ? this._password += tempC : this._username += tempC;\n            }\n            buffer = '';\n          } else if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c) {\n            cursor -= buffer.length;\n            buffer = '';\n            state = 'host';\n            continue;\n          } else {\n            buffer += c;\n          }\n          break;\n\n        case 'file host':\n          if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c) {\n            if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ':' || buffer[1] == '|')) {\n              state = 'relative path';\n            } else if (buffer.length == 0) {\n              state = 'relative path start';\n            } else {\n              this._host = IDNAToASCII.call(this, buffer);\n              buffer = '';\n              state = 'relative path start';\n            }\n            continue;\n          } else if ('\\t' == c || '\\n' == c || '\\r' == c) {\n            err('Invalid whitespace in file host.');\n          } else {\n            buffer += c;\n          }\n          break;\n\n        case 'host':\n        case 'hostname':\n          if (':' == c && !seenBracket) {\n            // XXX host parsing\n            this._host = IDNAToASCII.call(this, buffer);\n            buffer = '';\n            state = 'port';\n            if ('hostname' == stateOverride) {\n              break loop;\n            }\n          } else if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c) {\n            this._host = IDNAToASCII.call(this, buffer);\n            buffer = '';\n            state = 'relative path start';\n            if (stateOverride) {\n              break loop;\n            }\n            continue;\n          } else if ('\\t' != c && '\\n' != c && '\\r' != c) {\n            if ('[' == c) {\n              seenBracket = true;\n            } else if (']' == c) {\n              seenBracket = false;\n            }\n            buffer += c;\n          } else {\n            err('Invalid code point in host/hostname: ' + c);\n          }\n          break;\n\n        case 'port':\n          if (/[0-9]/.test(c)) {\n            buffer += c;\n          } else if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c || stateOverride) {\n            if ('' != buffer) {\n              var temp = parseInt(buffer, 10);\n              if (temp != relative[this._scheme]) {\n                this._port = temp + '';\n              }\n              buffer = '';\n            }\n            if (stateOverride) {\n              break loop;\n            }\n            state = 'relative path start';\n            continue;\n          } else if ('\\t' == c || '\\n' == c || '\\r' == c) {\n            err('Invalid code point in port: ' + c);\n          } else {\n            invalid.call(this);\n          }\n          break;\n\n        case 'relative path start':\n          if ('\\\\' == c)\n            err(\"'\\\\' not allowed in path.\");\n          state = 'relative path';\n          if ('/' != c && '\\\\' != c) {\n            continue;\n          }\n          break;\n\n        case 'relative path':\n          if (EOF == c || '/' == c || '\\\\' == c || (!stateOverride && ('?' == c || '#' == c))) {\n            if ('\\\\' == c) {\n              err('\\\\ not allowed in relative path.');\n            }\n            var tmp;\n            if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {\n              buffer = tmp;\n            }\n            if ('..' == buffer) {\n              this._path.pop();\n              if ('/' != c && '\\\\' != c) {\n                this._path.push('');\n              }\n            } else if ('.' == buffer && '/' != c && '\\\\' != c) {\n              this._path.push('');\n            } else if ('.' != buffer) {\n              if ('file' == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == '|') {\n                buffer = buffer[0] + ':';\n              }\n              this._path.push(buffer);\n            }\n            buffer = '';\n            if ('?' == c) {\n              this._query = '?';\n              state = 'query';\n            } else if ('#' == c) {\n              this._fragment = '#';\n              state = 'fragment';\n            }\n          } else if ('\\t' != c && '\\n' != c && '\\r' != c) {\n            buffer += percentEscape(c);\n          }\n          break;\n\n        case 'query':\n          if (!stateOverride && '#' == c) {\n            this._fragment = '#';\n            state = 'fragment';\n          } else if (EOF != c && '\\t' != c && '\\n' != c && '\\r' != c) {\n            this._query += percentEscapeQuery(c);\n          }\n          break;\n\n        case 'fragment':\n          if (EOF != c && '\\t' != c && '\\n' != c && '\\r' != c) {\n            this._fragment += c;\n          }\n          break;\n      }\n\n      cursor++;\n    }\n  }\n\n  function clear() {\n    this._scheme = '';\n    this._schemeData = '';\n    this._username = '';\n    this._password = null;\n    this._host = '';\n    this._port = '';\n    this._path = [];\n    this._query = '';\n    this._fragment = '';\n    this._isInvalid = false;\n    this._isRelative = false;\n  }\n\n  // Does not process domain names or IP addresses.\n  // Does not handle encoding for the query parameter.\n  function jURL(url, base /* , encoding */) {\n    if (base !== undefined && !(base instanceof jURL))\n      base = new jURL(String(base));\n\n    this._url = url;\n    clear.call(this);\n\n    var input = url.replace(/^[ \\t\\r\\n\\f]+|[ \\t\\r\\n\\f]+$/g, '');\n    // encoding = encoding || 'utf-8'\n\n    parse.call(this, input, null, base);\n  }\n\n  jURL.prototype = {\n    get href() {\n      if (this._isInvalid)\n        return this._url;\n\n      var authority = '';\n      if ('' != this._username || null != this._password) {\n        authority = this._username +\n            (null != this._password ? ':' + this._password : '') + '@';\n      }\n\n      return this.protocol +\n          (this._isRelative ? '//' + authority + this.host : '') +\n          this.pathname + this._query + this._fragment;\n    },\n    set href(href) {\n      clear.call(this);\n      parse.call(this, href);\n    },\n\n    get protocol() {\n      return this._scheme + ':';\n    },\n    set protocol(protocol) {\n      if (this._isInvalid)\n        return;\n      parse.call(this, protocol + ':', 'scheme start');\n    },\n\n    get host() {\n      return this._isInvalid ? '' : this._port ?\n          this._host + ':' + this._port : this._host;\n    },\n    set host(host) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      parse.call(this, host, 'host');\n    },\n\n    get hostname() {\n      return this._host;\n    },\n    set hostname(hostname) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      parse.call(this, hostname, 'hostname');\n    },\n\n    get port() {\n      return this._port;\n    },\n    set port(port) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      parse.call(this, port, 'port');\n    },\n\n    get pathname() {\n      return this._isInvalid ? '' : this._isRelative ?\n          '/' + this._path.join('/') : this._schemeData;\n    },\n    set pathname(pathname) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      this._path = [];\n      parse.call(this, pathname, 'relative path start');\n    },\n\n    get search() {\n      return this._isInvalid || !this._query || '?' == this._query ?\n          '' : this._query;\n    },\n    set search(search) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      this._query = '?';\n      if ('?' == search[0])\n        search = search.slice(1);\n      parse.call(this, search, 'query');\n    },\n\n    get hash() {\n      return this._isInvalid || !this._fragment || '#' == this._fragment ?\n          '' : this._fragment;\n    },\n    set hash(hash) {\n      if (this._isInvalid)\n        return;\n      this._fragment = '#';\n      if ('#' == hash[0])\n        hash = hash.slice(1);\n      parse.call(this, hash, 'fragment');\n    }\n  };\n\n  scope.URL = jURL;\n\n})(window);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n// Old versions of iOS do not have bind.\n\nif (!Function.prototype.bind) {\n  Function.prototype.bind = function(scope) {\n    var self = this;\n    var args = Array.prototype.slice.call(arguments, 1);\n    return function() {\n      var args2 = args.slice();\n      args2.push.apply(args2, arguments);\n      return self.apply(scope, args2);\n    };\n  };\n}\n\n// mixin\n\n// copy all properties from inProps (et al) to inObj\nfunction mixin(inObj/*, inProps, inMoreProps, ...*/) {\n  var obj = inObj || {};\n  for (var i = 1; i < arguments.length; i++) {\n    var p = arguments[i];\n    try {\n      for (var n in p) {\n        copyProperty(n, p, obj);\n      }\n    } catch(x) {\n    }\n  }\n  return obj;\n}\n\n// copy property inName from inSource object to inTarget object\nfunction copyProperty(inName, inSource, inTarget) {\n  var pd = getPropertyDescriptor(inSource, inName);\n  Object.defineProperty(inTarget, inName, pd);\n}\n\n// get property descriptor for inName on inObject, even if\n// inName exists on some link in inObject's prototype chain\nfunction getPropertyDescriptor(inObject, inName) {\n  if (inObject) {\n    var pd = Object.getOwnPropertyDescriptor(inObject, inName);\n    return pd || getPropertyDescriptor(Object.getPrototypeOf(inObject), inName);\n  }\n}\n\n// export\n\nscope.mixin = mixin;\n\n})(window.Platform);","// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(scope) {\n\n  'use strict';\n\n  // polyfill DOMTokenList\n  // * add/remove: allow these methods to take multiple classNames\n  // * toggle: add a 2nd argument which forces the given state rather\n  //  than toggling.\n\n  var add = DOMTokenList.prototype.add;\n  var remove = DOMTokenList.prototype.remove;\n  DOMTokenList.prototype.add = function() {\n    for (var i = 0; i < arguments.length; i++) {\n      add.call(this, arguments[i]);\n    }\n  };\n  DOMTokenList.prototype.remove = function() {\n    for (var i = 0; i < arguments.length; i++) {\n      remove.call(this, arguments[i]);\n    }\n  };\n  DOMTokenList.prototype.toggle = function(name, bool) {\n    if (arguments.length == 1) {\n      bool = !this.contains(name);\n    }\n    bool ? this.add(name) : this.remove(name);\n  };\n  DOMTokenList.prototype.switch = function(oldName, newName) {\n    oldName && this.remove(oldName);\n    newName && this.add(newName);\n  };\n\n  // add array() to NodeList, NamedNodeMap, HTMLCollection\n\n  var ArraySlice = function() {\n    return Array.prototype.slice.call(this);\n  };\n\n  var namedNodeMap = (window.NamedNodeMap || window.MozNamedAttrMap || {});\n\n  NodeList.prototype.array = ArraySlice;\n  namedNodeMap.prototype.array = ArraySlice;\n  HTMLCollection.prototype.array = ArraySlice;\n\n  // polyfill performance.now\n\n  if (!window.performance) {\n    var start = Date.now();\n    // only at millisecond precision\n    window.performance = {now: function(){ return Date.now() - start }};\n  }\n\n  // polyfill for requestAnimationFrame\n\n  if (!window.requestAnimationFrame) {\n    window.requestAnimationFrame = (function() {\n      var nativeRaf = window.webkitRequestAnimationFrame ||\n        window.mozRequestAnimationFrame;\n\n      return nativeRaf ?\n        function(callback) {\n          return nativeRaf(function() {\n            callback(performance.now());\n          });\n        } :\n        function( callback ){\n          return window.setTimeout(callback, 1000 / 60);\n        };\n    })();\n  }\n\n  if (!window.cancelAnimationFrame) {\n    window.cancelAnimationFrame = (function() {\n      return  window.webkitCancelAnimationFrame ||\n        window.mozCancelAnimationFrame ||\n        function(id) {\n          clearTimeout(id);\n        };\n    })();\n  }\n\n  // utility\n\n  function createDOM(inTagOrNode, inHTML, inAttrs) {\n    var dom = typeof inTagOrNode == 'string' ?\n        document.createElement(inTagOrNode) : inTagOrNode.cloneNode(true);\n    dom.innerHTML = inHTML;\n    if (inAttrs) {\n      for (var n in inAttrs) {\n        dom.setAttribute(n, inAttrs[n]);\n      }\n    }\n    return dom;\n  }\n  // Make a stub for Polymer() for polyfill purposes; under the HTMLImports\n  // polyfill, scripts in the main document run before imports. That means\n  // if (1) polymer is imported and (2) Polymer() is called in the main document\n  // in a script after the import, 2 occurs before 1. We correct this here\n  // by specfiically patching Polymer(); this is not necessary under native\n  // HTMLImports.\n  var elementDeclarations = [];\n\n  var polymerStub = function(name, dictionary) {\n    elementDeclarations.push(arguments);\n  }\n  window.Polymer = polymerStub;\n\n  // deliver queued delcarations\n  scope.deliverDeclarations = function() {\n    scope.deliverDeclarations = function() {\n     throw 'Possible attempt to load Polymer twice';\n    };\n    return elementDeclarations;\n  }\n\n  // Once DOMContent has loaded, any main document scripts that depend on\n  // Polymer() should have run. Calling Polymer() now is an error until\n  // polymer is imported.\n  window.addEventListener('DOMContentLoaded', function() {\n    if (window.Polymer === polymerStub) {\n      window.Polymer = function() {\n        console.error('You tried to use polymer without loading it first. To ' +\n          'load polymer, <link rel=\"import\" href=\"' + \n          'components/polymer/polymer.html\">');\n      };\n    }\n  });\n\n  // exports\n  scope.createDOM = createDOM;\n\n})(window.Platform);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// poor man's adapter for template.content on various platform scenarios\nwindow.templateContent = window.templateContent || function(inTemplate) {\n  return inTemplate.content;\n};","(function(scope) {\n  \n  scope = scope || (window.Inspector = {});\n  \n  var inspector;\n\n  window.sinspect = function(inNode, inProxy) {\n    if (!inspector) {\n      inspector = window.open('', 'ShadowDOM Inspector', null, true);\n      inspector.document.write(inspectorHTML);\n      //inspector.document.close();\n      inspector.api = {\n        shadowize: shadowize\n      };\n    }\n    inspect(inNode || wrap(document.body), inProxy);\n  };\n\n  var inspectorHTML = [\n    '<!DOCTYPE html>',\n    '<html>',\n    '  <head>',\n    '    <title>ShadowDOM Inspector</title>',\n    '    <style>',\n    '      body {',\n    '      }',\n    '      pre {',\n    '        font: 9pt \"Courier New\", monospace;',\n    '        line-height: 1.5em;',\n    '      }',\n    '      tag {',\n    '        color: purple;',\n    '      }',\n    '      ul {',\n    '         margin: 0;',\n    '         padding: 0;',\n    '         list-style: none;',\n    '      }',\n    '      li {',\n    '         display: inline-block;',\n    '         background-color: #f1f1f1;',\n    '         padding: 4px 6px;',\n    '         border-radius: 4px;',\n    '         margin-right: 4px;',\n    '      }',\n    '    </style>',\n    '  </head>',\n    '  <body>',\n    '    <ul id=\"crumbs\">',\n    '    </ul>',\n    '    <div id=\"tree\"></div>',\n    '  </body>',\n    '</html>'\n  ].join('\\n');\n  \n  var crumbs = [];\n\n  var displayCrumbs = function() {\n    // alias our document\n    var d = inspector.document;\n    // get crumbbar\n    var cb = d.querySelector('#crumbs');\n    // clear crumbs\n    cb.textContent = '';\n    // build new crumbs\n    for (var i=0, c; c=crumbs[i]; i++) {\n      var a = d.createElement('a');\n      a.href = '#';\n      a.textContent = c.localName;\n      a.idx = i;\n      a.onclick = function(event) {\n        var c;\n        while (crumbs.length > this.idx) {\n          c = crumbs.pop();\n        }\n        inspect(c.shadow || c, c);\n        event.preventDefault();\n      };\n      cb.appendChild(d.createElement('li')).appendChild(a);\n    }\n  };\n\n  var inspect = function(inNode, inProxy) {\n    // alias our document\n    var d = inspector.document;\n    // reset list of drillable nodes\n    drillable = [];\n    // memoize our crumb proxy\n    var proxy = inProxy || inNode;\n    crumbs.push(proxy);\n    // update crumbs\n    displayCrumbs();\n    // reflect local tree\n    d.body.querySelector('#tree').innerHTML =\n        '<pre>' + output(inNode, inNode.childNodes) + '</pre>';\n  };\n\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n\n  var blacklisted = {STYLE:1, SCRIPT:1, \"#comment\": 1, TEMPLATE: 1};\n  var blacklist = function(inNode) {\n    return blacklisted[inNode.nodeName];\n  };\n\n  var output = function(inNode, inChildNodes, inIndent) {\n    if (blacklist(inNode)) {\n      return '';\n    }\n    var indent = inIndent || '';\n    if (inNode.localName || inNode.nodeType == 11) {\n      var name = inNode.localName || 'shadow-root';\n      //inChildNodes = ShadowDOM.localNodes(inNode);\n      var info = indent + describe(inNode);\n      // if only textNodes\n      // TODO(sjmiles): make correct for ShadowDOM\n      /*if (!inNode.children.length && inNode.localName !== 'content' && inNode.localName !== 'shadow') {\n        info += catTextContent(inChildNodes);\n      } else*/ {\n        // TODO(sjmiles): native <shadow> has no reference to its projection\n        if (name == 'content' /*|| name == 'shadow'*/) {\n          inChildNodes = inNode.getDistributedNodes();\n        }\n        info += '<br/>';\n        var ind = indent + '&nbsp;&nbsp;';\n        forEach(inChildNodes, function(n) {\n          info += output(n, n.childNodes, ind);\n        });\n        info += indent;\n      }\n      if (!({br:1}[name])) {\n        info += '<tag>&lt;/' + name + '&gt;</tag>';\n        info += '<br/>';\n      }\n    } else {\n      var text = inNode.textContent.trim();\n      info = text ? indent + '\"' + text + '\"' + '<br/>' : '';\n    }\n    return info;\n  };\n\n  var catTextContent = function(inChildNodes) {\n    var info = '';\n    forEach(inChildNodes, function(n) {\n      info += n.textContent.trim();\n    });\n    return info;\n  };\n\n  var drillable = [];\n\n  var describe = function(inNode) {\n    var tag = '<tag>' + '&lt;';\n    var name = inNode.localName || 'shadow-root';\n    if (inNode.webkitShadowRoot || inNode.shadowRoot) {\n      tag += ' <button idx=\"' + drillable.length +\n        '\" onclick=\"api.shadowize.call(this)\">' + name + '</button>';\n      drillable.push(inNode);\n    } else {\n      tag += name || 'shadow-root';\n    }\n    if (inNode.attributes) {\n      forEach(inNode.attributes, function(a) {\n        tag += ' ' + a.name + (a.value ? '=\"' + a.value + '\"' : '');\n      });\n    }\n    tag += '&gt;'+ '</tag>';\n    return tag;\n  };\n\n  // remote api\n\n  shadowize = function() {\n    var idx = Number(this.attributes.idx.value);\n    //alert(idx);\n    var node = drillable[idx];\n    if (node) {\n      inspect(node.webkitShadowRoot || node.shadowRoot, node)\n    } else {\n      console.log(\"bad shadowize node\");\n      console.dir(this);\n    }\n  };\n  \n  // export\n  \n  scope.output = output;\n  \n})(window.Inspector);\n\n\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // TODO(sorvell): It's desireable to provide a default stylesheet \n  // that's convenient for styling unresolved elements, but\n  // it's cumbersome to have to include this manually in every page.\n  // It would make sense to put inside some HTMLImport but \n  // the HTMLImports polyfill does not allow loading of stylesheets \n  // that block rendering. Therefore this injection is tolerated here.\n\n  var style = document.createElement('style');\n  style.textContent = ''\n      + 'body {'\n      + 'transition: opacity ease-in 0.2s;' \n      + ' } \\n'\n      + 'body[unresolved] {'\n      + 'opacity: 0; display: block; overflow: hidden;' \n      + ' } \\n'\n      ;\n  var head = document.querySelector('head');\n  head.insertBefore(style, head.firstChild);\n\n})(Platform);\n","(function(scope) {\n\n  function withDependencies(task, depends) {\n    depends = depends || [];\n    if (!depends.map) {\n      depends = [depends];\n    }\n    return task.apply(this, depends.map(marshal));\n  }\n\n  function module(name, dependsOrFactory, moduleFactory) {\n    var module;\n    switch (arguments.length) {\n      case 0:\n        return;\n      case 1:\n        module = null;\n        break;\n      case 2:\n        module = dependsOrFactory.apply(this);\n        break;\n      default:\n        module = withDependencies(moduleFactory, dependsOrFactory);\n        break;\n    }\n    modules[name] = module;\n  };\n\n  function marshal(name) {\n    return modules[name];\n  }\n\n  var modules = {};\n\n  function using(depends, task) {\n    HTMLImports.whenImportsReady(function() {\n      withDependencies(task, depends);\n    });\n  };\n\n  // exports\n\n  scope.marshal = marshal;\n  scope.module = module;\n  scope.using = using;\n\n})(window);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\nvar iterations = 0;\nvar callbacks = [];\nvar twiddle = document.createTextNode('');\n\nfunction endOfMicrotask(callback) {\n  twiddle.textContent = iterations++;\n  callbacks.push(callback);\n}\n\nfunction atEndOfMicrotask() {\n  while (callbacks.length) {\n    callbacks.shift()();\n  }\n}\n\nnew (window.MutationObserver || JsMutationObserver)(atEndOfMicrotask)\n  .observe(twiddle, {characterData: true})\n  ;\n\n// exports\n\nscope.endOfMicrotask = endOfMicrotask;\n\n})(Platform);\n\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar urlResolver = {\n  resolveDom: function(root, url) {\n    url = url || root.ownerDocument.baseURI;\n    this.resolveAttributes(root, url);\n    this.resolveStyles(root, url);\n    // handle template.content\n    var templates = root.querySelectorAll('template');\n    if (templates) {\n      for (var i = 0, l = templates.length, t; (i < l) && (t = templates[i]); i++) {\n        if (t.content) {\n          this.resolveDom(t.content, url);\n        }\n      }\n    }\n  },\n  resolveTemplate: function(template) {\n    this.resolveDom(template.content, template.ownerDocument.baseURI);\n  },\n  resolveStyles: function(root, url) {\n    var styles = root.querySelectorAll('style');\n    if (styles) {\n      for (var i = 0, l = styles.length, s; (i < l) && (s = styles[i]); i++) {\n        this.resolveStyle(s, url);\n      }\n    }\n  },\n  resolveStyle: function(style, url) {\n    url = url || style.ownerDocument.baseURI;\n    style.textContent = this.resolveCssText(style.textContent, url);\n  },\n  resolveCssText: function(cssText, baseUrl) {\n    cssText = replaceUrlsInCssText(cssText, baseUrl, CSS_URL_REGEXP);\n    return replaceUrlsInCssText(cssText, baseUrl, CSS_IMPORT_REGEXP);\n  },\n  resolveAttributes: function(root, url) {\n    if (root.hasAttributes && root.hasAttributes()) {\n      this.resolveElementAttributes(root, url);\n    }\n    // search for attributes that host urls\n    var nodes = root && root.querySelectorAll(URL_ATTRS_SELECTOR);\n    if (nodes) {\n      for (var i = 0, l = nodes.length, n; (i < l) && (n = nodes[i]); i++) {\n        this.resolveElementAttributes(n, url);\n      }\n    }\n  },\n  resolveElementAttributes: function(node, url) {\n    url = url || node.ownerDocument.baseURI;\n    URL_ATTRS.forEach(function(v) {\n      var attr = node.attributes[v];\n      if (attr && attr.value &&\n         (attr.value.search(URL_TEMPLATE_SEARCH) < 0)) {\n        var urlPath = resolveRelativeUrl(url, attr.value);\n        attr.value = urlPath;\n      }\n    });\n  }\n};\n\nvar CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\nvar CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\nvar URL_ATTRS = ['href', 'src', 'action'];\nvar URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';\nvar URL_TEMPLATE_SEARCH = '{{.*}}';\n\nfunction replaceUrlsInCssText(cssText, baseUrl, regexp) {\n  return cssText.replace(regexp, function(m, pre, url, post) {\n    var urlPath = url.replace(/[\"']/g, '');\n    urlPath = resolveRelativeUrl(baseUrl, urlPath);\n    return pre + '\\'' + urlPath + '\\'' + post;\n  });\n}\n\nfunction resolveRelativeUrl(baseUrl, url) {\n  var u = new URL(url, baseUrl);\n  return makeDocumentRelPath(u.href);\n}\n\nfunction makeDocumentRelPath(url) {\n  var root = document.baseURI;\n  var u = new URL(url, root);\n  if (u.host === root.host && u.port === root.port &&\n      u.protocol === root.protocol) {\n    return makeRelPath(root.pathname, u.pathname);\n  } else {\n    return url;\n  }\n}\n\n// make a relative path from source to target\nfunction makeRelPath(source, target) {\n  var s = source.split('/');\n  var t = target.split('/');\n  while (s.length && s[0] === t[0]){\n    s.shift();\n    t.shift();\n  }\n  for (var i = 0, l = s.length - 1; i < l; i++) {\n    t.unshift('..');\n  }\n  return t.join('/');\n}\n\n// exports\nscope.urlResolver = urlResolver;\n\n})(Platform);\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(global) {\n\n  var registrationsTable = new WeakMap();\n\n  // We use setImmediate or postMessage for our future callback.\n  var setImmediate = window.msSetImmediate;\n\n  // Use post message to emulate setImmediate.\n  if (!setImmediate) {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener('message', function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, '*');\n    };\n  }\n\n  // This is used to ensure that we never schedule 2 callas to setImmediate\n  var isScheduled = false;\n\n  // Keep track of observers that needs to be notified next time.\n  var scheduledObservers = [];\n\n  /**\n   * Schedules |dispatchCallback| to be called in the future.\n   * @param {MutationObserver} observer\n   */\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill &&\n        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||\n        node;\n  }\n\n  function dispatchCallbacks() {\n    // http://dom.spec.whatwg.org/#mutation-observers\n\n    isScheduled = false; // Used to allow a new setImmediate call above.\n\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    // Sort observers based on their creation UID (incremental).\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n\n      // 2.1, 2.2\n      var queue = observer.takeRecords();\n      // 2.3. Remove all transient registered observers whose observer is mo.\n      removeTransientObserversFor(observer);\n\n      // 2.4\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n\n    // 3.\n    if (anyNonEmpty)\n      dispatchCallbacks();\n  }\n\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer)\n          registration.removeTransientObservers();\n      });\n    });\n  }\n\n  /**\n   * This function is used for the \"For each registered observer observer (with\n   * observer's options as options) in target's list of registered observers,\n   * run these substeps:\" and the \"For each ancestor ancestor of target, and for\n   * each registered observer observer (with options options) in ancestor's list\n   * of registered observers, run these substeps:\" part of the algorithms. The\n   * |options.subtree| is checked to ensure that the callback is called\n   * correctly.\n   *\n   * @param {Node} target\n   * @param {function(MutationObserverInit):MutationRecord} callback\n   */\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n\n          // Only target ignores subtree.\n          if (node !== target && !options.subtree)\n            continue;\n\n          var record = callback(options);\n          if (record)\n            registration.enqueue(record);\n        }\n      }\n    }\n  }\n\n  var uidCounter = 0;\n\n  /**\n   * The class that maps to the DOM MutationObserver interface.\n   * @param {Function} callback.\n   * @constructor\n   */\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n\n      // 1.1\n      if (!options.childList && !options.attributes && !options.characterData ||\n\n          // 1.2\n          options.attributeOldValue && !options.attributes ||\n\n          // 1.3\n          options.attributeFilter && options.attributeFilter.length &&\n              !options.attributes ||\n\n          // 1.4\n          options.characterDataOldValue && !options.characterData) {\n\n        throw new SyntaxError();\n      }\n\n      var registrations = registrationsTable.get(target);\n      if (!registrations)\n        registrationsTable.set(target, registrations = []);\n\n      // 2\n      // If target's list of registered observers already includes a registered\n      // observer associated with the context object, replace that registered\n      // observer's options with options.\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n\n      // 3.\n      // Otherwise, add a new registered observer to target's list of registered\n      // observers with the context object as the observer and options as the\n      // options, and add target to context object's list of nodes on which it\n      // is registered.\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n\n      registration.addListeners();\n    },\n\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n\n  /**\n   * @param {string} type\n   * @param {Node} target\n   * @constructor\n   */\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  };\n\n  // We keep track of the two (possibly one) records used in a single mutation.\n  var currentRecord, recordWithOldValue;\n\n  /**\n   * Creates a record without |oldValue| and caches it as |currentRecord| for\n   * later use.\n   * @param {string} oldValue\n   * @return {MutationRecord}\n   */\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n\n  /**\n   * Gets or creates a record with |oldValue| based in the |currentRecord|\n   * @param {string} oldValue\n   * @return {MutationRecord}\n   */\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue)\n      return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n\n  /**\n   * @param {MutationRecord} record\n   * @return {boolean} Whether the record represents a record from the current\n   * mutation event.\n   */\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n\n  /**\n   * Selects which record, if any, to replace the last record in the queue.\n   * This returns |null| if no record should be replaced.\n   *\n   * @param {MutationRecord} lastRecord\n   * @param {MutationRecord} newRecord\n   * @param {MutationRecord}\n   */\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord)\n      return lastRecord;\n\n    // Check if the the record we are adding represents the same record. If\n    // so, we keep the one with the oldValue in it.\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))\n      return recordWithOldValue;\n\n    return null;\n  }\n\n  /**\n   * Class used to represent a registered observer.\n   * @param {MutationObserver} observer\n   * @param {Node} target\n   * @param {MutationObserverInit} options\n   * @constructor\n   */\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n\n      // There are cases where we replace the last record with the new record.\n      // For example if the record represents the same mutation we need to use\n      // the one with the oldValue. If we get same record (this can happen as we\n      // walk up the tree) we ignore the new record.\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n\n      records[length] = record;\n    },\n\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes)\n        node.addEventListener('DOMAttrModified', this, true);\n\n      if (options.characterData)\n        node.addEventListener('DOMCharacterDataModified', this, true);\n\n      if (options.childList)\n        node.addEventListener('DOMNodeInserted', this, true);\n\n      if (options.childList || options.subtree)\n        node.addEventListener('DOMNodeRemoved', this, true);\n    },\n\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes)\n        node.removeEventListener('DOMAttrModified', this, true);\n\n      if (options.characterData)\n        node.removeEventListener('DOMCharacterDataModified', this, true);\n\n      if (options.childList)\n        node.removeEventListener('DOMNodeInserted', this, true);\n\n      if (options.childList || options.subtree)\n        node.removeEventListener('DOMNodeRemoved', this, true);\n    },\n\n    /**\n     * Adds a transient observer on node. The transient observer gets removed\n     * next time we deliver the change records.\n     * @param {Node} node\n     */\n    addTransientObserver: function(node) {\n      // Don't add transient observers on the target itself. We already have all\n      // the required listeners set up on the target.\n      if (node === this.target)\n        return;\n\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        registrationsTable.set(node, registrations = []);\n\n      // We know that registrations does not contain this because we already\n      // checked if node === this.target.\n      registrations.push(this);\n    },\n\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n\n      transientObservedNodes.forEach(function(node) {\n        // Transient observers are never added to the target.\n        this.removeListeners_(node);\n\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n    },\n\n    handleEvent: function(e) {\n      // Stop propagation since we are managing the propagation manually.\n      // This means that other mutation events on the page will not work\n      // correctly but that is by design.\n      e.stopImmediatePropagation();\n\n      switch (e.type) {\n        case 'DOMAttrModified':\n          // http://dom.spec.whatwg.org/#concept-mo-queue-attributes\n\n          var name = e.attrName;\n          var namespace = e.relatedNode.namespaceURI;\n          var target = e.target;\n\n          // 1.\n          var record = new getRecord('attributes', target);\n          record.attributeName = name;\n          record.attributeNamespace = namespace;\n\n          // 2.\n          var oldValue =\n              e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 3.1, 4.2\n            if (!options.attributes)\n              return;\n\n            // 3.2, 4.3\n            if (options.attributeFilter && options.attributeFilter.length &&\n                options.attributeFilter.indexOf(name) === -1 &&\n                options.attributeFilter.indexOf(namespace) === -1) {\n              return;\n            }\n            // 3.3, 4.4\n            if (options.attributeOldValue)\n              return getRecordWithOldValue(oldValue);\n\n            // 3.4, 4.5\n            return record;\n          });\n\n          break;\n\n        case 'DOMCharacterDataModified':\n          // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata\n          var target = e.target;\n\n          // 1.\n          var record = getRecord('characterData', target);\n\n          // 2.\n          var oldValue = e.prevValue;\n\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 3.1, 4.2\n            if (!options.characterData)\n              return;\n\n            // 3.2, 4.3\n            if (options.characterDataOldValue)\n              return getRecordWithOldValue(oldValue);\n\n            // 3.3, 4.4\n            return record;\n          });\n\n          break;\n\n        case 'DOMNodeRemoved':\n          this.addTransientObserver(e.target);\n          // Fall through.\n        case 'DOMNodeInserted':\n          // http://dom.spec.whatwg.org/#concept-mo-queue-childlist\n          var target = e.relatedNode;\n          var changedNode = e.target;\n          var addedNodes, removedNodes;\n          if (e.type === 'DOMNodeInserted') {\n            addedNodes = [changedNode];\n            removedNodes = [];\n          } else {\n\n            addedNodes = [];\n            removedNodes = [changedNode];\n          }\n          var previousSibling = changedNode.previousSibling;\n          var nextSibling = changedNode.nextSibling;\n\n          // 1.\n          var record = getRecord('childList', target);\n          record.addedNodes = addedNodes;\n          record.removedNodes = removedNodes;\n          record.previousSibling = previousSibling;\n          record.nextSibling = nextSibling;\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 2.1, 3.2\n            if (!options.childList)\n              return;\n\n            // 2.2, 3.3\n            return record;\n          });\n\n      }\n\n      clearRecords();\n    }\n  };\n\n  global.JsMutationObserver = JsMutationObserver;\n\n  if (!global.MutationObserver)\n    global.MutationObserver = JsMutationObserver;\n\n\n})(this);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\nwindow.HTMLImports = window.HTMLImports || {flags:{}};","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  // imports\n  var path = scope.path;\n  var xhr = scope.xhr;\n  var flags = scope.flags;\n\n  // TODO(sorvell): this loader supports a dynamic list of urls\n  // and an oncomplete callback that is called when the loader is done.\n  // The polyfill currently does *not* need this dynamism or the onComplete\n  // concept. Because of this, the loader could be simplified quite a bit.\n  var Loader = function(onLoad, onComplete) {\n    this.cache = {};\n    this.onload = onLoad;\n    this.oncomplete = onComplete;\n    this.inflight = 0;\n    this.pending = {};\n  };\n\n  Loader.prototype = {\n    addNodes: function(nodes) {\n      // number of transactions to complete\n      this.inflight += nodes.length;\n      // commence transactions\n      for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {\n        this.require(n);\n      }\n      // anything to do?\n      this.checkDone();\n    },\n    addNode: function(node) {\n      // number of transactions to complete\n      this.inflight++;\n      // commence transactions\n      this.require(node);\n      // anything to do?\n      this.checkDone();\n    },\n    require: function(elt) {\n      var url = elt.src || elt.href;\n      // ensure we have a standard url that can be used\n      // reliably for deduping.\n      // TODO(sjmiles): ad-hoc\n      elt.__nodeUrl = url;\n      // deduplication\n      if (!this.dedupe(url, elt)) {\n        // fetch this resource\n        this.fetch(url, elt);\n      }\n    },\n    dedupe: function(url, elt) {\n      if (this.pending[url]) {\n        // add to list of nodes waiting for inUrl\n        this.pending[url].push(elt);\n        // don't need fetch\n        return true;\n      }\n      var resource;\n      if (this.cache[url]) {\n        this.onload(url, elt, this.cache[url]);\n        // finished this transaction\n        this.tail();\n        // don't need fetch\n        return true;\n      }\n      // first node waiting for inUrl\n      this.pending[url] = [elt];\n      // need fetch (not a dupe)\n      return false;\n    },\n    fetch: function(url, elt) {\n      flags.load && console.log('fetch', url, elt);\n      var receiveXhr = function(err, resource) {\n        this.receive(url, elt, err, resource);\n      }.bind(this);\n      xhr.load(url, receiveXhr);\n      // TODO(sorvell): blocked on\n      // https://code.google.com/p/chromium/issues/detail?id=257221\n      // xhr'ing for a document makes scripts in imports runnable; otherwise\n      // they are not; however, it requires that we have doctype=html in\n      // the import which is unacceptable. This is only needed on Chrome\n      // to avoid the bug above.\n      /*\n      if (isDocumentLink(elt)) {\n        xhr.loadDocument(url, receiveXhr);\n      } else {\n        xhr.load(url, receiveXhr);\n      }\n      */\n    },\n    receive: function(url, elt, err, resource) {\n      this.cache[url] = resource;\n      var $p = this.pending[url];\n      for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {\n        //if (!err) {\n          this.onload(url, p, resource);\n        //}\n        this.tail();\n      }\n      this.pending[url] = null;\n    },\n    tail: function() {\n      --this.inflight;\n      this.checkDone();\n    },\n    checkDone: function() {\n      if (!this.inflight) {\n        this.oncomplete();\n      }\n    }\n  };\n\n  xhr = xhr || {\n    async: true,\n    ok: function(request) {\n      return (request.status >= 200 && request.status < 300)\n          || (request.status === 304)\n          || (request.status === 0);\n    },\n    load: function(url, next, nextContext) {\n      var request = new XMLHttpRequest();\n      if (scope.flags.debug || scope.flags.bust) {\n        url += '?' + Math.random();\n      }\n      request.open('GET', url, xhr.async);\n      request.addEventListener('readystatechange', function(e) {\n        if (request.readyState === 4) {\n          next.call(nextContext, !xhr.ok(request) && request,\n              request.response || request.responseText, url);\n        }\n      });\n      request.send();\n      return request;\n    },\n    loadDocument: function(url, next, nextContext) {\n      this.load(url, next, nextContext).responseType = 'document';\n    }\n  };\n\n  // exports\n  scope.xhr = xhr;\n  scope.Loader = Loader;\n\n})(window.HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar IMPORT_LINK_TYPE = 'import';\nvar flags = scope.flags;\nvar isIe = /Trident/.test(navigator.userAgent);\n// TODO(sorvell): SD polyfill intrusion\nvar mainDoc = window.ShadowDOMPolyfill ? \n    window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\n// importParser\n// highlander object to manage parsing of imports\n// parses import related elements\n// and ensures proper parse order\n// parse order is enforced by crawling the tree and monitoring which elements\n// have been parsed; async parsing is also supported.\n\n// highlander object for parsing a document tree\nvar importParser = {\n  // parse selectors for main document elements\n  documentSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',\n  // parse selectors for import document elements\n  importsSelectors: [\n    'link[rel=' + IMPORT_LINK_TYPE + ']',\n    'link[rel=stylesheet]',\n    'style',\n    'script:not([type])',\n    'script[type=\"text/javascript\"]'\n  ].join(','),\n  map: {\n    link: 'parseLink',\n    script: 'parseScript',\n    style: 'parseStyle'\n  },\n  // try to parse the next import in the tree\n  parseNext: function() {\n    var next = this.nextToParse();\n    if (next) {\n      this.parse(next);\n    }\n  },\n  parse: function(elt) {\n    if (this.isParsed(elt)) {\n      flags.parse && console.log('[%s] is already parsed', elt.localName);\n      return;\n    }\n    var fn = this[this.map[elt.localName]];\n    if (fn) {\n      this.markParsing(elt);\n      fn.call(this, elt);\n    }\n  },\n  // only 1 element may be parsed at a time; parsing is async so, each\n  // parsing implementation must inform the system that parsing is complete\n  // via markParsingComplete.\n  markParsing: function(elt) {\n    flags.parse && console.log('parsing', elt);\n    this.parsingElement = elt;\n  },\n  markParsingComplete: function(elt) {\n    elt.__importParsed = true;\n    if (elt.__importElement) {\n      elt.__importElement.__importParsed = true;\n    }\n    this.parsingElement = null;\n    flags.parse && console.log('completed', elt);\n    this.parseNext();\n  },\n  parseImport: function(elt) {\n    elt.import.__importParsed = true;\n    // TODO(sorvell): consider if there's a better way to do this;\n    // expose an imports parsing hook; this is needed, for example, by the\n    // CustomElements polyfill.\n    if (HTMLImports.__importsParsingHook) {\n      HTMLImports.__importsParsingHook(elt);\n    }\n    // fire load event\n    if (elt.__resource) {\n      elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));    \n    } else {\n      elt.dispatchEvent(new CustomEvent('error', {bubbles: false}));\n    }\n    // TODO(sorvell): workaround for Safari addEventListener not working\n    // for elements not in the main document.\n    if (elt.__pending) {\n      var fn;\n      while (elt.__pending.length) {\n        fn = elt.__pending.shift();\n        if (fn) {\n          fn({target: elt});\n        }\n      }\n    }\n    this.markParsingComplete(elt);\n  },\n  parseLink: function(linkElt) {\n    if (nodeIsImport(linkElt)) {\n      this.parseImport(linkElt);\n    } else {\n      // make href absolute\n      linkElt.href = linkElt.href;\n      this.parseGeneric(linkElt);\n    }\n  },\n  parseStyle: function(elt) {\n    // TODO(sorvell): style element load event can just not fire so clone styles\n    var src = elt;\n    elt = cloneStyle(elt);\n    elt.__importElement = src;\n    this.parseGeneric(elt);\n  },\n  parseGeneric: function(elt) {\n    this.trackElement(elt);\n    document.head.appendChild(elt);\n  },\n  // tracks when a loadable element has loaded\n  trackElement: function(elt, callback) {\n    var self = this;\n    var done = function(e) {\n      if (callback) {\n        callback(e);\n      }\n      self.markParsingComplete(elt);\n    };\n    elt.addEventListener('load', done);\n    elt.addEventListener('error', done);\n\n    // NOTE: IE does not fire \"load\" event for styles that have already loaded\n    // This is in violation of the spec, so we try our hardest to work around it\n    if (isIe && elt.localName === 'style') {\n      var fakeLoad = false;\n      // If there's not @import in the textContent, assume it has loaded\n      if (elt.textContent.indexOf('@import') == -1) {\n        fakeLoad = true;\n      // if we have a sheet, we have been parsed\n      } else if (elt.sheet) {\n        fakeLoad = true;\n        var csr = elt.sheet.cssRules;\n        var len = csr ? csr.length : 0;\n        // search the rules for @import's\n        for (var i = 0, r; (i < len) && (r = csr[i]); i++) {\n          if (r.type === CSSRule.IMPORT_RULE) {\n            // if every @import has resolved, fake the load\n            fakeLoad = fakeLoad && Boolean(r.styleSheet);\n          }\n        }\n      }\n      // dispatch a fake load event and continue parsing\n      if (fakeLoad) {\n        elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));\n      }\n    }\n  },\n  // NOTE: execute scripts by injecting them and watching for the load/error\n  // event. Inline scripts are handled via dataURL's because browsers tend to\n  // provide correct parsing errors in this case. If this has any compatibility\n  // issues, we can switch to injecting the inline script with textContent.\n  // Scripts with dataURL's do not appear to generate load events and therefore\n  // we assume they execute synchronously.\n  parseScript: function(scriptElt) {\n    var script = document.createElement('script');\n    script.__importElement = scriptElt;\n    script.src = scriptElt.src ? scriptElt.src : \n        generateScriptDataUrl(scriptElt);\n    scope.currentScript = scriptElt;\n    this.trackElement(script, function(e) {\n      script.parentNode.removeChild(script);\n      scope.currentScript = null;  \n    });\n    document.head.appendChild(script);\n  },\n  // determine the next element in the tree which should be parsed\n  nextToParse: function() {\n    return !this.parsingElement && this.nextToParseInDoc(mainDoc);\n  },\n  nextToParseInDoc: function(doc, link) {\n    var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));\n    for (var i=0, l=nodes.length, p=0, n; (i<l) && (n=nodes[i]); i++) {\n      if (!this.isParsed(n)) {\n        if (this.hasResource(n)) {\n          return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;\n        } else {\n          return;\n        }\n      }\n    }\n    // all nodes have been parsed, ready to parse import, if any\n    return link;\n  },\n  // return the set of parse selectors relevant for this node.\n  parseSelectorsForNode: function(node) {\n    var doc = node.ownerDocument || node;\n    return doc === mainDoc ? this.documentSelectors : this.importsSelectors;\n  },\n  isParsed: function(node) {\n    return node.__importParsed;\n  },\n  hasResource: function(node) {\n    if (nodeIsImport(node) && !node.import) {\n      return false;\n    }\n    return true;\n  }\n};\n\nfunction nodeIsImport(elt) {\n  return (elt.localName === 'link') && (elt.rel === IMPORT_LINK_TYPE);\n}\n\nfunction generateScriptDataUrl(script) {\n  var scriptContent = generateScriptContent(script), b64;\n  try {\n    b64 = btoa(scriptContent);\n  } catch(e) {\n    b64 = btoa(unescape(encodeURIComponent(scriptContent)));\n    console.warn('Script contained non-latin characters that were forced ' +\n      'to latin. Some characters may be wrong.', script);\n  }\n  return 'data:text/javascript;base64,' + b64;\n}\n\nfunction generateScriptContent(script) {\n  return script.textContent + generateSourceMapHint(script);\n}\n\n// calculate source map hint\nfunction generateSourceMapHint(script) {\n  var moniker = script.__nodeUrl;\n  if (!moniker) {\n    moniker = script.ownerDocument.baseURI;\n    // there could be more than one script this url\n    var tag = '[' + Math.floor((Math.random()+1)*1000) + ']';\n    // TODO(sjmiles): Polymer hack, should be pluggable if we need to allow \n    // this sort of thing\n    var matches = script.textContent.match(/Polymer\\(['\"]([^'\"]*)/);\n    tag = matches && matches[1] || tag;\n    // tag the moniker\n    moniker += '/' + tag + '.js';\n  }\n  return '\\n//# sourceURL=' + moniker + '\\n';\n}\n\n// style/stylesheet handling\n\n// clone style with proper path resolution for main document\n// NOTE: styles are the only elements that require direct path fixup.\nfunction cloneStyle(style) {\n  var clone = style.ownerDocument.createElement('style');\n  clone.textContent = style.textContent;\n  path.resolveUrlsInStyle(clone);\n  return clone;\n}\n\n// path fixup: style elements in imports must be made relative to the main \n// document. We fixup url's in url() and @import.\nvar CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\nvar CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\n\nvar path = {\n  resolveUrlsInStyle: function(style) {\n    var doc = style.ownerDocument;\n    var resolver = doc.createElement('a');\n    style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);\n    return style;  \n  },\n  resolveUrlsInCssText: function(cssText, urlObj) {\n    var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);\n    r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);\n    return r;\n  },\n  replaceUrls: function(text, urlObj, regexp) {\n    return text.replace(regexp, function(m, pre, url, post) {\n      var urlPath = url.replace(/[\"']/g, '');\n      urlObj.href = urlPath;\n      urlPath = urlObj.href;\n      return pre + '\\'' + urlPath + '\\'' + post;\n    });    \n  }\n}\n\n// exports\nscope.parser = importParser;\nscope.path = path;\nscope.isIE = isIe;\n\n})(HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar hasNative = ('import' in document.createElement('link'));\nvar useNative = hasNative;\nvar flags = scope.flags;\nvar IMPORT_LINK_TYPE = 'import';\n\n// TODO(sorvell): SD polyfill intrusion\nvar mainDoc = window.ShadowDOMPolyfill ? \n    ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\nif (!useNative) {\n\n  // imports\n  var xhr = scope.xhr;\n  var Loader = scope.Loader;\n  var parser = scope.parser;\n\n  // importer\n  // highlander object to manage loading of imports\n\n  // for any document, importer:\n  // - loads any linked import documents (with deduping)\n\n  var importer = {\n    documents: {},\n    // nodes to load in the mian document\n    documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',\n    // nodes to load in imports\n    importsPreloadSelectors: [\n      'link[rel=' + IMPORT_LINK_TYPE + ']'\n    ].join(','),\n    loadNode: function(node) {\n      importLoader.addNode(node);\n    },\n    // load all loadable elements within the parent element\n    loadSubtree: function(parent) {\n      var nodes = this.marshalNodes(parent);\n      // add these nodes to loader's queue\n      importLoader.addNodes(nodes);\n    },\n    marshalNodes: function(parent) {\n      // all preloadable nodes in inDocument\n      return parent.querySelectorAll(this.loadSelectorsForNode(parent));\n    },\n    // find the proper set of load selectors for a given node\n    loadSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === mainDoc ? this.documentPreloadSelectors :\n          this.importsPreloadSelectors;\n    },\n    loaded: function(url, elt, resource) {\n      flags.load && console.log('loaded', url, elt);\n      // store generic resource\n      // TODO(sorvell): fails for nodes inside <template>.content\n      // see https://code.google.com/p/chromium/issues/detail?id=249381.\n      elt.__resource = resource;\n      if (isDocumentLink(elt)) {\n        var doc = this.documents[url];\n        // if we've never seen a document at this url\n        if (!doc) {\n          // generate an HTMLDocument from data\n          doc = makeDocument(resource, url);\n          doc.__importLink = elt;\n          // TODO(sorvell): we cannot use MO to detect parsed nodes because\n          // SD polyfill does not report these as mutations.\n          this.bootDocument(doc);\n          // cache document\n          this.documents[url] = doc;\n        }\n        // don't store import record until we're actually loaded\n        // store document resource\n        elt.import = doc;\n      }\n      parser.parseNext();\n    },\n    bootDocument: function(doc) {\n      this.loadSubtree(doc);\n      this.observe(doc);\n      parser.parseNext();\n    },\n    loadedAll: function() {\n      parser.parseNext();\n    }\n  };\n\n  // loader singleton\n  var importLoader = new Loader(importer.loaded.bind(importer), \n      importer.loadedAll.bind(importer));\n\n  function isDocumentLink(elt) {\n    return isLinkRel(elt, IMPORT_LINK_TYPE);\n  }\n\n  function isLinkRel(elt, rel) {\n    return elt.localName === 'link' && elt.getAttribute('rel') === rel;\n  }\n\n  function isScript(elt) {\n    return elt.localName === 'script';\n  }\n\n  function makeDocument(resource, url) {\n    // create a new HTML document\n    var doc = resource;\n    if (!(doc instanceof Document)) {\n      doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);\n    }\n    // cache the new document's source url\n    doc._URL = url;\n    // establish a relative path via <base>\n    var base = doc.createElement('base');\n    base.setAttribute('href', url);\n    // add baseURI support to browsers (IE) that lack it.\n    if (!doc.baseURI) {\n      doc.baseURI = url;\n    }\n    // ensure UTF-8 charset\n    var meta = doc.createElement('meta');\n    meta.setAttribute('charset', 'utf-8');\n\n    doc.head.appendChild(meta);\n    doc.head.appendChild(base);\n    // install HTML last as it may trigger CustomElement upgrades\n    // TODO(sjmiles): problem wrt to template boostrapping below,\n    // template bootstrapping must (?) come before element upgrade\n    // but we cannot bootstrap templates until they are in a document\n    // which is too late\n    if (!(resource instanceof Document)) {\n      // install html\n      doc.body.innerHTML = resource;\n    }\n    // TODO(sorvell): ideally this code is not aware of Template polyfill,\n    // but for now the polyfill needs help to bootstrap these templates\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(doc);\n    }\n    return doc;\n  }\n} else {\n  // do nothing if using native imports\n  var importer = {};\n}\n\n// NOTE: We cannot polyfill document.currentScript because it's not possible\n// both to override and maintain the ability to capture the native value;\n// therefore we choose to expose _currentScript both when native imports\n// and the polyfill are in use.\nvar currentScriptDescriptor = {\n  get: function() {\n    return HTMLImports.currentScript || document.currentScript;\n  },\n  configurable: true\n};\n\nObject.defineProperty(document, '_currentScript', currentScriptDescriptor);\nObject.defineProperty(mainDoc, '_currentScript', currentScriptDescriptor);\n\n// Polyfill document.baseURI for browsers without it.\nif (!document.baseURI) {\n  var baseURIDescriptor = {\n    get: function() {\n      return window.location.href;\n    },\n    configurable: true\n  };\n\n  Object.defineProperty(document, 'baseURI', baseURIDescriptor);\n  Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor);\n}\n\n// call a callback when all HTMLImports in the document at call (or at least\n//  document ready) time have loaded.\n// 1. ensure the document is in a ready state (has dom), then \n// 2. watch for loading of imports and call callback when done\nfunction whenImportsReady(callback, doc) {\n  doc = doc || mainDoc;\n  // if document is loading, wait and try again\n  whenDocumentReady(function() {\n    watchImportsLoad(callback, doc);\n  }, doc);\n}\n\n// call the callback when the document is in a ready state (has dom)\nvar requiredReadyState = HTMLImports.isIE ? 'complete' : 'interactive';\nvar READY_EVENT = 'readystatechange';\nfunction isDocumentReady(doc) {\n  return (doc.readyState === 'complete' ||\n      doc.readyState === requiredReadyState);\n}\n\n// call <callback> when we ensure the document is in a ready state\nfunction whenDocumentReady(callback, doc) {\n  if (!isDocumentReady(doc)) {\n    var checkReady = function() {\n      if (doc.readyState === 'complete' || \n          doc.readyState === requiredReadyState) {\n        doc.removeEventListener(READY_EVENT, checkReady);\n        whenDocumentReady(callback, doc);\n      }\n    }\n    doc.addEventListener(READY_EVENT, checkReady);\n  } else if (callback) {\n    callback();\n  }\n}\n\n// call <callback> when we ensure all imports have loaded\nfunction watchImportsLoad(callback, doc) {\n  var imports = doc.querySelectorAll('link[rel=import]');\n  var loaded = 0, l = imports.length;\n  function checkDone(d) { \n    if (loaded == l) {\n      // go async to ensure parser isn't stuck on a script tag\n      requestAnimationFrame(callback);\n    }\n  }\n  function loadedImport(e) {\n    loaded++;\n    checkDone();\n  }\n  if (l) {\n    for (var i=0, imp; (i<l) && (imp=imports[i]); i++) {\n      if (isImportLoaded(imp)) {\n        loadedImport.call(imp);\n      } else {\n        imp.addEventListener('load', loadedImport);\n        imp.addEventListener('error', loadedImport);\n      }\n    }\n  } else {\n    checkDone();\n  }\n}\n\nfunction isImportLoaded(link) {\n  return useNative ? (link.import && (link.import.readyState !== 'loading')) :\n      link.__importParsed;\n}\n\n// exports\nscope.hasNative = hasNative;\nscope.useNative = useNative;\nscope.importer = importer;\nscope.whenImportsReady = whenImportsReady;\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\nscope.isImportLoaded = isImportLoaded;\nscope.importLoader = importLoader;\n\n})(window.HTMLImports);\n"," /*\nCopyright 2013 The Polymer Authors. All rights reserved.\nUse of this source code is governed by a BSD-style\nlicense that can be found in the LICENSE file.\n*/\n\n(function(scope){\n\nvar IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\nvar importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';\nvar importer = scope.importer;\n\n// we track mutations for addedNodes, looking for imports\nfunction handler(mutations) {\n  for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) {\n    if (m.type === 'childList' && m.addedNodes.length) {\n      addedNodes(m.addedNodes);\n    }\n  }\n}\n\n// find loadable elements and add them to the importer\nfunction addedNodes(nodes) {\n  for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {\n    if (shouldLoadNode(n)) {\n      importer.loadNode(n);\n    }\n    if (n.children && n.children.length) {\n      addedNodes(n.children);\n    }\n  }\n}\n\nfunction shouldLoadNode(node) {\n  return (node.nodeType === 1) && matches.call(node,\n      importer.loadSelectorsForNode(node));\n}\n\n// x-plat matches\nvar matches = HTMLElement.prototype.matches || \n    HTMLElement.prototype.matchesSelector || \n    HTMLElement.prototype.webkitMatchesSelector ||\n    HTMLElement.prototype.mozMatchesSelector ||\n    HTMLElement.prototype.msMatchesSelector;\n\nvar observer = new MutationObserver(handler);\n\n// observe the given root for loadable elements\nfunction observe(root) {\n  observer.observe(root, {childList: true, subtree: true});\n}\n\n// exports\n// TODO(sorvell): factor so can put on scope\nscope.observe = observe;\nimporter.observe = observe;\n\n})(HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(){\n\n// bootstrap\n\n// IE shim for CustomEvent\nif (typeof window.CustomEvent !== 'function') {\n  window.CustomEvent = function(inType, dictionary) {\n     var e = document.createEvent('HTMLEvents');\n     e.initEvent(inType,\n        dictionary.bubbles === false ? false : true,\n        dictionary.cancelable === false ? false : true,\n        dictionary.detail);\n     return e;\n  };\n}\n\n// TODO(sorvell): SD polyfill intrusion\nvar doc = window.ShadowDOMPolyfill ? \n    window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\n// Fire the 'HTMLImportsLoaded' event when imports in document at load time \n// have loaded. This event is required to simulate the script blocking \n// behavior of native imports. A main document script that needs to be sure\n// imports have loaded should wait for this event.\nHTMLImports.whenImportsReady(function() {\n  HTMLImports.ready = true;\n  HTMLImports.readyTime = new Date().getTime();\n  doc.dispatchEvent(\n    new CustomEvent('HTMLImportsLoaded', {bubbles: true})\n  );\n});\n\n\n// no need to bootstrap the polyfill when native imports is available.\nif (!HTMLImports.useNative) {\n  function bootstrap() {\n    HTMLImports.importer.bootDocument(doc);\n  }\n    \n  // TODO(sorvell): SD polyfill does *not* generate mutations for nodes added\n  // by the parser. For this reason, we must wait until the dom exists to \n  // bootstrap.\n  if (document.readyState === 'complete' ||\n      (document.readyState === 'interactive' && !window.attachEvent)) {\n    bootstrap();\n  } else {\n    document.addEventListener('DOMContentLoaded', bootstrap);\n  }\n}\n\n})();\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\nwindow.CustomElements = window.CustomElements || {flags:{}};"," /*\r\nCopyright 2013 The Polymer Authors. All rights reserved.\r\nUse of this source code is governed by a BSD-style\r\nlicense that can be found in the LICENSE file.\r\n*/\r\n\r\n(function(scope){\r\n\r\nvar logFlags = window.logFlags || {};\r\nvar IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';\r\n\r\n// walk the subtree rooted at node, applying 'find(element, data)' function\r\n// to each element\r\n// if 'find' returns true for 'element', do not search element's subtree\r\nfunction findAll(node, find, data) {\r\n  var e = node.firstElementChild;\r\n  if (!e) {\r\n    e = node.firstChild;\r\n    while (e && e.nodeType !== Node.ELEMENT_NODE) {\r\n      e = e.nextSibling;\r\n    }\r\n  }\r\n  while (e) {\r\n    if (find(e, data) !== true) {\r\n      findAll(e, find, data);\r\n    }\r\n    e = e.nextElementSibling;\r\n  }\r\n  return null;\r\n}\r\n\r\n// walk all shadowRoots on a given node.\r\nfunction forRoots(node, cb) {\r\n  var root = node.shadowRoot;\r\n  while(root) {\r\n    forSubtree(root, cb);\r\n    root = root.olderShadowRoot;\r\n  }\r\n}\r\n\r\n// walk the subtree rooted at node, including descent into shadow-roots,\r\n// applying 'cb' to each element\r\nfunction forSubtree(node, cb) {\r\n  //logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);\r\n  findAll(node, function(e) {\r\n    if (cb(e)) {\r\n      return true;\r\n    }\r\n    forRoots(e, cb);\r\n  });\r\n  forRoots(node, cb);\r\n  //logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();\r\n}\r\n\r\n// manage lifecycle on added node\r\nfunction added(node) {\r\n  if (upgrade(node)) {\r\n    insertedNode(node);\r\n    return true;\r\n  }\r\n  inserted(node);\r\n}\r\n\r\n// manage lifecycle on added node's subtree only\r\nfunction addedSubtree(node) {\r\n  forSubtree(node, function(e) {\r\n    if (added(e)) {\r\n      return true;\r\n    }\r\n  });\r\n}\r\n\r\n// manage lifecycle on added node and it's subtree\r\nfunction addedNode(node) {\r\n  return added(node) || addedSubtree(node);\r\n}\r\n\r\n// upgrade custom elements at node, if applicable\r\nfunction upgrade(node) {\r\n  if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {\r\n    var type = node.getAttribute('is') || node.localName;\r\n    var definition = scope.registry[type];\r\n    if (definition) {\r\n      logFlags.dom && console.group('upgrade:', node.localName);\r\n      scope.upgrade(node);\r\n      logFlags.dom && console.groupEnd();\r\n      return true;\r\n    }\r\n  }\r\n}\r\n\r\nfunction insertedNode(node) {\r\n  inserted(node);\r\n  if (inDocument(node)) {\r\n    forSubtree(node, function(e) {\r\n      inserted(e);\r\n    });\r\n  }\r\n}\r\n\r\n// TODO(sorvell): on platforms without MutationObserver, mutations may not be\r\n// reliable and therefore attached/detached are not reliable.\r\n// To make these callbacks less likely to fail, we defer all inserts and removes\r\n// to give a chance for elements to be inserted into dom.\r\n// This ensures attachedCallback fires for elements that are created and\r\n// immediately added to dom.\r\nvar hasPolyfillMutations = (!window.MutationObserver ||\r\n    (window.MutationObserver === window.JsMutationObserver));\r\nscope.hasPolyfillMutations = hasPolyfillMutations;\r\n\r\nvar isPendingMutations = false;\r\nvar pendingMutations = [];\r\nfunction deferMutation(fn) {\r\n  pendingMutations.push(fn);\r\n  if (!isPendingMutations) {\r\n    isPendingMutations = true;\r\n    var async = (window.Platform && window.Platform.endOfMicrotask) ||\r\n        setTimeout;\r\n    async(takeMutations);\r\n  }\r\n}\r\n\r\nfunction takeMutations() {\r\n  isPendingMutations = false;\r\n  var $p = pendingMutations;\r\n  for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {\r\n    p();\r\n  }\r\n  pendingMutations = [];\r\n}\r\n\r\nfunction inserted(element) {\r\n  if (hasPolyfillMutations) {\r\n    deferMutation(function() {\r\n      _inserted(element);\r\n    });\r\n  } else {\r\n    _inserted(element);\r\n  }\r\n}\r\n\r\n// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this\r\nfunction _inserted(element) {\r\n  // TODO(sjmiles): it's possible we were inserted and removed in the space\r\n  // of one microtask, in which case we won't be 'inDocument' here\r\n  // But there are other cases where we are testing for inserted without\r\n  // specific knowledge of mutations, and must test 'inDocument' to determine\r\n  // whether to call inserted\r\n  // If we can factor these cases into separate code paths we can have\r\n  // better diagnostics.\r\n  // TODO(sjmiles): when logging, do work on all custom elements so we can\r\n  // track behavior even when callbacks not defined\r\n  //console.log('inserted: ', element.localName);\r\n  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {\r\n    logFlags.dom && console.group('inserted:', element.localName);\r\n    if (inDocument(element)) {\r\n      element.__inserted = (element.__inserted || 0) + 1;\r\n      // if we are in a 'removed' state, bluntly adjust to an 'inserted' state\r\n      if (element.__inserted < 1) {\r\n        element.__inserted = 1;\r\n      }\r\n      // if we are 'over inserted', squelch the callback\r\n      if (element.__inserted > 1) {\r\n        logFlags.dom && console.warn('inserted:', element.localName,\r\n          'insert/remove count:', element.__inserted)\r\n      } else if (element.attachedCallback) {\r\n        logFlags.dom && console.log('inserted:', element.localName);\r\n        element.attachedCallback();\r\n      }\r\n    }\r\n    logFlags.dom && console.groupEnd();\r\n  }\r\n}\r\n\r\nfunction removedNode(node) {\r\n  removed(node);\r\n  forSubtree(node, function(e) {\r\n    removed(e);\r\n  });\r\n}\r\n\r\nfunction removed(element) {\r\n  if (hasPolyfillMutations) {\r\n    deferMutation(function() {\r\n      _removed(element);\r\n    });\r\n  } else {\r\n    _removed(element);\r\n  }\r\n}\r\n\r\nfunction _removed(element) {\r\n  // TODO(sjmiles): temporary: do work on all custom elements so we can track\r\n  // behavior even when callbacks not defined\r\n  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {\r\n    logFlags.dom && console.group('removed:', element.localName);\r\n    if (!inDocument(element)) {\r\n      element.__inserted = (element.__inserted || 0) - 1;\r\n      // if we are in a 'inserted' state, bluntly adjust to an 'removed' state\r\n      if (element.__inserted > 0) {\r\n        element.__inserted = 0;\r\n      }\r\n      // if we are 'over removed', squelch the callback\r\n      if (element.__inserted < 0) {\r\n        logFlags.dom && console.warn('removed:', element.localName,\r\n            'insert/remove count:', element.__inserted)\r\n      } else if (element.detachedCallback) {\r\n        element.detachedCallback();\r\n      }\r\n    }\r\n    logFlags.dom && console.groupEnd();\r\n  }\r\n}\r\n\r\n// SD polyfill intrustion due mainly to the fact that 'document'\r\n// is not entirely wrapped\r\nfunction wrapIfNeeded(node) {\r\n  return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)\r\n      : node;\r\n}\r\n\r\nfunction inDocument(element) {\r\n  var p = element;\r\n  var doc = wrapIfNeeded(document);\r\n  while (p) {\r\n    if (p == doc) {\r\n      return true;\r\n    }\r\n    p = p.parentNode || p.host;\r\n  }\r\n}\r\n\r\nfunction watchShadow(node) {\r\n  if (node.shadowRoot && !node.shadowRoot.__watched) {\r\n    logFlags.dom && console.log('watching shadow-root for: ', node.localName);\r\n    // watch all unwatched roots...\r\n    var root = node.shadowRoot;\r\n    while (root) {\r\n      watchRoot(root);\r\n      root = root.olderShadowRoot;\r\n    }\r\n  }\r\n}\r\n\r\nfunction watchRoot(root) {\r\n  if (!root.__watched) {\r\n    observe(root);\r\n    root.__watched = true;\r\n  }\r\n}\r\n\r\nfunction handler(mutations) {\r\n  //\r\n  if (logFlags.dom) {\r\n    var mx = mutations[0];\r\n    if (mx && mx.type === 'childList' && mx.addedNodes) {\r\n        if (mx.addedNodes) {\r\n          var d = mx.addedNodes[0];\r\n          while (d && d !== document && !d.host) {\r\n            d = d.parentNode;\r\n          }\r\n          var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';\r\n          u = u.split('/?').shift().split('/').pop();\r\n        }\r\n    }\r\n    console.group('mutations (%d) [%s]', mutations.length, u || '');\r\n  }\r\n  //\r\n  mutations.forEach(function(mx) {\r\n    //logFlags.dom && console.group('mutation');\r\n    if (mx.type === 'childList') {\r\n      forEach(mx.addedNodes, function(n) {\r\n        //logFlags.dom && console.log(n.localName);\r\n        if (!n.localName) {\r\n          return;\r\n        }\r\n        // nodes added may need lifecycle management\r\n        addedNode(n);\r\n      });\r\n      // removed nodes may need lifecycle management\r\n      forEach(mx.removedNodes, function(n) {\r\n        //logFlags.dom && console.log(n.localName);\r\n        if (!n.localName) {\r\n          return;\r\n        }\r\n        removedNode(n);\r\n      });\r\n    }\r\n    //logFlags.dom && console.groupEnd();\r\n  });\r\n  logFlags.dom && console.groupEnd();\r\n};\r\n\r\nvar observer = new MutationObserver(handler);\r\n\r\nfunction takeRecords() {\r\n  // TODO(sjmiles): ask Raf why we have to call handler ourselves\r\n  handler(observer.takeRecords());\r\n  takeMutations();\r\n}\r\n\r\nvar forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\r\n\r\nfunction observe(inRoot) {\r\n  observer.observe(inRoot, {childList: true, subtree: true});\r\n}\r\n\r\nfunction observeDocument(doc) {\r\n  observe(doc);\r\n}\r\n\r\nfunction upgradeDocument(doc) {\r\n  logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());\r\n  addedNode(doc);\r\n  logFlags.dom && console.groupEnd();\r\n}\r\n\r\nfunction upgradeDocumentTree(doc) {\r\n  doc = wrapIfNeeded(doc);\r\n  //console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());\r\n  // upgrade contained imported documents\r\n  var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');\r\n  for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {\r\n    if (n.import && n.import.__parsed) {\r\n      upgradeDocumentTree(n.import);\r\n    }\r\n  }\r\n  upgradeDocument(doc);\r\n}\r\n\r\n// exports\r\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\r\nscope.watchShadow = watchShadow;\r\nscope.upgradeDocumentTree = upgradeDocumentTree;\r\nscope.upgradeAll = addedNode;\r\nscope.upgradeSubtree = addedSubtree;\r\nscope.insertedNode = insertedNode;\r\n\r\nscope.observeDocument = observeDocument;\r\nscope.upgradeDocument = upgradeDocument;\r\n\r\nscope.takeRecords = takeRecords;\r\n\r\n})(window.CustomElements);\r\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Implements `document.register`\n * @module CustomElements\n*/\n\n/**\n * Polyfilled extensions to the `document` object.\n * @class Document\n*/\n\n(function(scope) {\n\n// imports\n\nif (!scope) {\n  scope = window.CustomElements = {flags:{}};\n}\nvar flags = scope.flags;\n\n// native document.registerElement?\n\nvar hasNative = Boolean(document.registerElement);\n// TODO(sorvell): See https://github.com/Polymer/polymer/issues/399\n// we'll address this by defaulting to CE polyfill in the presence of the SD\n// polyfill. This will avoid spamming excess attached/detached callbacks.\n// If there is a compelling need to run CE native with SD polyfill,\n// we'll need to fix this issue.\nvar useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;\n\nif (useNative) {\n\n  // stub\n  var nop = function() {};\n\n  // exports\n  scope.registry = {};\n  scope.upgradeElement = nop;\n\n  scope.watchShadow = nop;\n  scope.upgrade = nop;\n  scope.upgradeAll = nop;\n  scope.upgradeSubtree = nop;\n  scope.observeDocument = nop;\n  scope.upgradeDocument = nop;\n  scope.upgradeDocumentTree = nop;\n  scope.takeRecords = nop;\n\n} else {\n\n  /**\n   * Registers a custom tag name with the document.\n   *\n   * When a registered element is created, a `readyCallback` method is called\n   * in the scope of the element. The `readyCallback` method can be specified on\n   * either `options.prototype` or `options.lifecycle` with the latter taking\n   * precedence.\n   *\n   * @method register\n   * @param {String} name The tag name to register. Must include a dash ('-'),\n   *    for example 'x-component'.\n   * @param {Object} options\n   *    @param {String} [options.extends]\n   *      (_off spec_) Tag name of an element to extend (or blank for a new\n   *      element). This parameter is not part of the specification, but instead\n   *      is a hint for the polyfill because the extendee is difficult to infer.\n   *      Remember that the input prototype must chain to the extended element's\n   *      prototype (or HTMLElement.prototype) regardless of the value of\n   *      `extends`.\n   *    @param {Object} options.prototype The prototype to use for the new\n   *      element. The prototype must inherit from HTMLElement.\n   *    @param {Object} [options.lifecycle]\n   *      Callbacks that fire at important phases in the life of the custom\n   *      element.\n   *\n   * @example\n   *      FancyButton = document.registerElement(\"fancy-button\", {\n   *        extends: 'button',\n   *        prototype: Object.create(HTMLButtonElement.prototype, {\n   *          readyCallback: {\n   *            value: function() {\n   *              console.log(\"a fancy-button was created\",\n   *            }\n   *          }\n   *        })\n   *      });\n   * @return {Function} Constructor for the newly registered type.\n   */\n  function register(name, options) {\n    //console.warn('document.registerElement(\"' + name + '\", ', options, ')');\n    // construct a defintion out of options\n    // TODO(sjmiles): probably should clone options instead of mutating it\n    var definition = options || {};\n    if (!name) {\n      // TODO(sjmiles): replace with more appropriate error (EricB can probably\n      // offer guidance)\n      throw new Error('document.registerElement: first argument `name` must not be empty');\n    }\n    if (name.indexOf('-') < 0) {\n      // TODO(sjmiles): replace with more appropriate error (EricB can probably\n      // offer guidance)\n      throw new Error('document.registerElement: first argument (\\'name\\') must contain a dash (\\'-\\'). Argument provided was \\'' + String(name) + '\\'.');\n    }\n    // elements may only be registered once\n    if (getRegisteredDefinition(name)) {\n      throw new Error('DuplicateDefinitionError: a type with name \\'' + String(name) + '\\' is already registered');\n    }\n    // must have a prototype, default to an extension of HTMLElement\n    // TODO(sjmiles): probably should throw if no prototype, check spec\n    if (!definition.prototype) {\n      // TODO(sjmiles): replace with more appropriate error (EricB can probably\n      // offer guidance)\n      throw new Error('Options missing required prototype property');\n    }\n    // record name\n    definition.__name = name.toLowerCase();\n    // ensure a lifecycle object so we don't have to null test it\n    definition.lifecycle = definition.lifecycle || {};\n    // build a list of ancestral custom elements (for native base detection)\n    // TODO(sjmiles): we used to need to store this, but current code only\n    // uses it in 'resolveTagName': it should probably be inlined\n    definition.ancestry = ancestry(definition.extends);\n    // extensions of native specializations of HTMLElement require localName\n    // to remain native, and use secondary 'is' specifier for extension type\n    resolveTagName(definition);\n    // some platforms require modifications to the user-supplied prototype\n    // chain\n    resolvePrototypeChain(definition);\n    // overrides to implement attributeChanged callback\n    overrideAttributeApi(definition.prototype);\n    // 7.1.5: Register the DEFINITION with DOCUMENT\n    registerDefinition(definition.__name, definition);\n    // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE\n    // 7.1.8. Return the output of the previous step.\n    definition.ctor = generateConstructor(definition);\n    definition.ctor.prototype = definition.prototype;\n    // force our .constructor to be our actual constructor\n    definition.prototype.constructor = definition.ctor;\n    // if initial parsing is complete\n    if (scope.ready) {\n      // upgrade any pre-existing nodes of this type\n      scope.upgradeDocumentTree(document);\n    }\n    return definition.ctor;\n  }\n\n  function ancestry(extnds) {\n    var extendee = getRegisteredDefinition(extnds);\n    if (extendee) {\n      return ancestry(extendee.extends).concat([extendee]);\n    }\n    return [];\n  }\n\n  function resolveTagName(definition) {\n    // if we are explicitly extending something, that thing is our\n    // baseTag, unless it represents a custom component\n    var baseTag = definition.extends;\n    // if our ancestry includes custom components, we only have a\n    // baseTag if one of them does\n    for (var i=0, a; (a=definition.ancestry[i]); i++) {\n      baseTag = a.is && a.tag;\n    }\n    // our tag is our baseTag, if it exists, and otherwise just our name\n    definition.tag = baseTag || definition.__name;\n    if (baseTag) {\n      // if there is a base tag, use secondary 'is' specifier\n      definition.is = definition.__name;\n    }\n  }\n\n  function resolvePrototypeChain(definition) {\n    // if we don't support __proto__ we need to locate the native level\n    // prototype for precise mixing in\n    if (!Object.__proto__) {\n      // default prototype\n      var nativePrototype = HTMLElement.prototype;\n      // work out prototype when using type-extension\n      if (definition.is) {\n        var inst = document.createElement(definition.tag);\n        nativePrototype = Object.getPrototypeOf(inst);\n      }\n      // ensure __proto__ reference is installed at each point on the prototype\n      // chain.\n      // NOTE: On platforms without __proto__, a mixin strategy is used instead\n      // of prototype swizzling. In this case, this generated __proto__ provides\n      // limited support for prototype traversal.\n      var proto = definition.prototype, ancestor;\n      while (proto && (proto !== nativePrototype)) {\n        var ancestor = Object.getPrototypeOf(proto);\n        proto.__proto__ = ancestor;\n        proto = ancestor;\n      }\n    }\n    // cache this in case of mixin\n    definition.native = nativePrototype;\n  }\n\n  // SECTION 4\n\n  function instantiate(definition) {\n    // 4.a.1. Create a new object that implements PROTOTYPE\n    // 4.a.2. Let ELEMENT by this new object\n    //\n    // the custom element instantiation algorithm must also ensure that the\n    // output is a valid DOM element with the proper wrapper in place.\n    //\n    return upgrade(domCreateElement(definition.tag), definition);\n  }\n\n  function upgrade(element, definition) {\n    // some definitions specify an 'is' attribute\n    if (definition.is) {\n      element.setAttribute('is', definition.is);\n    }\n    // remove 'unresolved' attr, which is a standin for :unresolved.\n    element.removeAttribute('unresolved');\n    // make 'element' implement definition.prototype\n    implement(element, definition);\n    // flag as upgraded\n    element.__upgraded__ = true;\n    // lifecycle management\n    created(element);\n    // attachedCallback fires in tree order, call before recursing\n    scope.insertedNode(element);\n    // there should never be a shadow root on element at this point\n    scope.upgradeSubtree(element);\n    // OUTPUT\n    return element;\n  }\n\n  function implement(element, definition) {\n    // prototype swizzling is best\n    if (Object.__proto__) {\n      element.__proto__ = definition.prototype;\n    } else {\n      // where above we can re-acquire inPrototype via\n      // getPrototypeOf(Element), we cannot do so when\n      // we use mixin, so we install a magic reference\n      customMixin(element, definition.prototype, definition.native);\n      element.__proto__ = definition.prototype;\n    }\n  }\n\n  function customMixin(inTarget, inSrc, inNative) {\n    // TODO(sjmiles): 'used' allows us to only copy the 'youngest' version of\n    // any property. This set should be precalculated. We also need to\n    // consider this for supporting 'super'.\n    var used = {};\n    // start with inSrc\n    var p = inSrc;\n    // The default is HTMLElement.prototype, so we add a test to avoid mixing in\n    // native prototypes\n    while (p !== inNative && p !== HTMLElement.prototype) {\n      var keys = Object.getOwnPropertyNames(p);\n      for (var i=0, k; k=keys[i]; i++) {\n        if (!used[k]) {\n          Object.defineProperty(inTarget, k,\n              Object.getOwnPropertyDescriptor(p, k));\n          used[k] = 1;\n        }\n      }\n      p = Object.getPrototypeOf(p);\n    }\n  }\n\n  function created(element) {\n    // invoke createdCallback\n    if (element.createdCallback) {\n      element.createdCallback();\n    }\n  }\n\n  // attribute watching\n\n  function overrideAttributeApi(prototype) {\n    // overrides to implement callbacks\n    // TODO(sjmiles): should support access via .attributes NamedNodeMap\n    // TODO(sjmiles): preserves user defined overrides, if any\n    if (prototype.setAttribute._polyfilled) {\n      return;\n    }\n    var setAttribute = prototype.setAttribute;\n    prototype.setAttribute = function(name, value) {\n      changeAttribute.call(this, name, value, setAttribute);\n    }\n    var removeAttribute = prototype.removeAttribute;\n    prototype.removeAttribute = function(name) {\n      changeAttribute.call(this, name, null, removeAttribute);\n    }\n    prototype.setAttribute._polyfilled = true;\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/\n  // index.html#dfn-attribute-changed-callback\n  function changeAttribute(name, value, operation) {\n    var oldValue = this.getAttribute(name);\n    operation.apply(this, arguments);\n    var newValue = this.getAttribute(name);\n    if (this.attributeChangedCallback\n        && (newValue !== oldValue)) {\n      this.attributeChangedCallback(name, oldValue, newValue);\n    }\n  }\n\n  // element registry (maps tag names to definitions)\n\n  var registry = {};\n\n  function getRegisteredDefinition(name) {\n    if (name) {\n      return registry[name.toLowerCase()];\n    }\n  }\n\n  function registerDefinition(name, definition) {\n    registry[name] = definition;\n  }\n\n  function generateConstructor(definition) {\n    return function() {\n      return instantiate(definition);\n    };\n  }\n\n  var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n  function createElementNS(namespace, tag, typeExtension) {\n    // NOTE: we do not support non-HTML elements,\n    // just call createElementNS for non HTML Elements\n    if (namespace === HTML_NAMESPACE) {\n      return createElement(tag, typeExtension);\n    } else {\n      return domCreateElementNS(namespace, tag);\n    }\n  }\n\n  function createElement(tag, typeExtension) {\n    // TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could\n    // error check it, or perhaps there should only ever be one argument\n    var definition = getRegisteredDefinition(typeExtension || tag);\n    if (definition) {\n      if (tag == definition.tag && typeExtension == definition.is) {\n        return new definition.ctor();\n      }\n      // Handle empty string for type extension.\n      if (!typeExtension && !definition.is) {\n        return new definition.ctor();\n      }\n    }\n\n    if (typeExtension) {\n      var element = createElement(tag);\n      element.setAttribute('is', typeExtension);\n      return element;\n    }\n    var element = domCreateElement(tag);\n    // Custom tags should be HTMLElements even if not upgraded.\n    if (tag.indexOf('-') >= 0) {\n      implement(element, HTMLElement);\n    }\n    return element;\n  }\n\n  function upgradeElement(element) {\n    if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) {\n      var is = element.getAttribute('is');\n      var definition = getRegisteredDefinition(is || element.localName);\n      if (definition) {\n        if (is && definition.tag == element.localName) {\n          return upgrade(element, definition);\n        } else if (!is && !definition.extends) {\n          return upgrade(element, definition);\n        }\n      }\n    }\n  }\n\n  function cloneNode(deep) {\n    // call original clone\n    var n = domCloneNode.call(this, deep);\n    // upgrade the element and subtree\n    scope.upgradeAll(n);\n    // return the clone\n    return n;\n  }\n  // capture native createElement before we override it\n\n  var domCreateElement = document.createElement.bind(document);\n  var domCreateElementNS = document.createElementNS.bind(document);\n\n  // capture native cloneNode before we override it\n\n  var domCloneNode = Node.prototype.cloneNode;\n\n  // exports\n\n  document.registerElement = register;\n  document.createElement = createElement; // override\n  document.createElementNS = createElementNS; // override\n  Node.prototype.cloneNode = cloneNode; // override\n\n  scope.registry = registry;\n\n  /**\n   * Upgrade an element to a custom element. Upgrading an element\n   * causes the custom prototype to be applied, an `is` attribute\n   * to be attached (as needed), and invocation of the `readyCallback`.\n   * `upgrade` does nothing if the element is already upgraded, or\n   * if it matches no registered custom tag name.\n   *\n   * @method ugprade\n   * @param {Element} element The element to upgrade.\n   * @return {Element} The upgraded element.\n   */\n  scope.upgrade = upgradeElement;\n}\n\n// Create a custom 'instanceof'. This is necessary when CustomElements\n// are implemented via a mixin strategy, as for example on IE10.\nvar isInstance;\nif (!Object.__proto__ && !useNative) {\n  isInstance = function(obj, ctor) {\n    var p = obj;\n    while (p) {\n      // NOTE: this is not technically correct since we're not checking if\n      // an object is an instance of a constructor; however, this should\n      // be good enough for the mixin strategy.\n      if (p === ctor.prototype) {\n        return true;\n      }\n      p = p.__proto__;\n    }\n    return false;\n  }\n} else {\n  isInstance = function(obj, base) {\n    return obj instanceof base;\n  }\n}\n\n// exports\nscope.instanceof = isInstance;\n\n// bc\ndocument.register = document.registerElement;\n\nscope.hasNative = hasNative;\nscope.useNative = useNative;\n\n})(window.CustomElements);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n// import\n\nvar IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n\n// highlander object for parsing a document tree\n\nvar parser = {\n  selectors: [\n    'link[rel=' + IMPORT_LINK_TYPE + ']'\n  ],\n  map: {\n    link: 'parseLink'\n  },\n  parse: function(inDocument) {\n    if (!inDocument.__parsed) {\n      // only parse once\n      inDocument.__parsed = true;\n      // all parsable elements in inDocument (depth-first pre-order traversal)\n      var elts = inDocument.querySelectorAll(parser.selectors);\n      // for each parsable node type, call the mapped parsing method\n      forEach(elts, function(e) {\n        parser[parser.map[e.localName]](e);\n      });\n      // upgrade all upgradeable static elements, anything dynamically\n      // created should be caught by observer\n      CustomElements.upgradeDocument(inDocument);\n      // observe document for dom changes\n      CustomElements.observeDocument(inDocument);\n    }\n  },\n  parseLink: function(linkElt) {\n    // imports\n    if (isDocumentLink(linkElt)) {\n      this.parseImport(linkElt);\n    }\n  },\n  parseImport: function(linkElt) {\n    if (linkElt.import) {\n      parser.parse(linkElt.import);\n    }\n  }\n};\n\nfunction isDocumentLink(inElt) {\n  return (inElt.localName === 'link'\n      && inElt.getAttribute('rel') === IMPORT_LINK_TYPE);\n}\n\nvar forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n\n// exports\n\nscope.parser = parser;\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\n\n})(window.CustomElements);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope){\n\n// bootstrap parsing\nfunction bootstrap() {\n  // parse document\n  CustomElements.parser.parse(document);\n  // one more pass before register is 'live'\n  CustomElements.upgradeDocument(document);\n  // choose async\n  var async = window.Platform && Platform.endOfMicrotask ? \n    Platform.endOfMicrotask :\n    setTimeout;\n  async(function() {\n    // set internal 'ready' flag, now document.registerElement will trigger \n    // synchronous upgrades\n    CustomElements.ready = true;\n    // capture blunt profiling data\n    CustomElements.readyTime = Date.now();\n    if (window.HTMLImports) {\n      CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;\n    }\n    // notify the system that we are bootstrapped\n    document.dispatchEvent(\n      new CustomEvent('WebComponentsReady', {bubbles: true})\n    );\n\n    // install upgrade hook if HTMLImports are available\n    if (window.HTMLImports) {\n      HTMLImports.__importsParsingHook = function(elt) {\n        CustomElements.parser.parse(elt.import);\n      }\n    }\n  });\n}\n\n// CustomEvent shim for IE\nif (typeof window.CustomEvent !== 'function') {\n  window.CustomEvent = function(inType) {\n    var e = document.createEvent('HTMLEvents');\n    e.initEvent(inType, true, true);\n    return e;\n  };\n}\n\n// When loading at readyState complete time (or via flag), boot custom elements\n// immediately.\n// If relevant, HTMLImports must already be loaded.\nif (document.readyState === 'complete' || scope.flags.eager) {\n  bootstrap();\n// When loading at readyState interactive time, bootstrap only if HTMLImports\n// are not pending. Also avoid IE as the semantics of this state are unreliable.\n} else if (document.readyState === 'interactive' && !window.attachEvent &&\n    (!window.HTMLImports || window.HTMLImports.ready)) {\n  bootstrap();\n// When loading at other readyStates, wait for the appropriate DOM event to \n// bootstrap.\n} else {\n  var loadEvent = window.HTMLImports && !HTMLImports.ready ?\n      'HTMLImportsLoaded' : 'DOMContentLoaded';\n  window.addEventListener(loadEvent, bootstrap);\n}\n\n})(window.CustomElements);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n\nif (window.ShadowDOMPolyfill) {\n\n  // ensure wrapped inputs for these functions\n  var fns = ['upgradeAll', 'upgradeSubtree', 'observeDocument',\n      'upgradeDocument'];\n\n  // cache originals\n  var original = {};\n  fns.forEach(function(fn) {\n    original[fn] = CustomElements[fn];\n  });\n\n  // override\n  fns.forEach(function(fn) {\n    CustomElements[fn] = function(inNode) {\n      return original[fn](wrap(inNode));\n    };\n  });\n\n}\n\n})();\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n  var endOfMicrotask = scope.endOfMicrotask;\n\n  // Generic url loader\n  function Loader(regex) {\n    this.regex = regex;\n  }\n  Loader.prototype = {\n    // TODO(dfreedm): there may be a better factoring here\n    // extract absolute urls from the text (full of relative urls)\n    extractUrls: function(text, base) {\n      var matches = [];\n      var matched, u;\n      while ((matched = this.regex.exec(text))) {\n        u = new URL(matched[1], base);\n        matches.push({matched: matched[0], url: u.href});\n      }\n      return matches;\n    },\n    // take a text blob, a root url, and a callback and load all the urls found within the text\n    // returns a map of absolute url to text\n    process: function(text, root, callback) {\n      var matches = this.extractUrls(text, root);\n      this.fetch(matches, {}, callback);\n    },\n    // build a mapping of url -> text from matches\n    fetch: function(matches, map, callback) {\n      var inflight = matches.length;\n\n      // return early if there is no fetching to be done\n      if (!inflight) {\n        return callback(map);\n      }\n\n      var done = function() {\n        if (--inflight === 0) {\n          callback(map);\n        }\n      };\n\n      // map url -> responseText\n      var handleXhr = function(err, request) {\n        var match = request.match;\n        var key = match.url;\n        // handle errors with an empty string\n        if (err) {\n          map[key] = '';\n          return done();\n        }\n        var response = request.response || request.responseText;\n        map[key] = response;\n        this.fetch(this.extractUrls(response, key), map, done);\n      };\n\n      var m, req, url;\n      for (var i = 0; i < inflight; i++) {\n        m = matches[i];\n        url = m.url;\n        // if this url has already been requested, skip requesting it again\n        if (map[url]) {\n          // Async call to done to simplify the inflight logic\n          endOfMicrotask(done);\n          continue;\n        }\n        req = this.xhr(url, handleXhr, this);\n        req.match = m;\n        // tag the map with an XHR request to deduplicate at the same level\n        map[url] = req;\n      }\n    },\n    xhr: function(url, callback, scope) {\n      var request = new XMLHttpRequest();\n      request.open('GET', url, true);\n      request.send();\n      request.onload = function() {\n        callback.call(scope, null, request);\n      };\n      request.onerror = function() {\n        callback.call(scope, null, request);\n      };\n      return request;\n    }\n  };\n\n  scope.Loader = Loader;\n})(window.Platform);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\nvar urlResolver = scope.urlResolver;\nvar Loader = scope.Loader;\n\nfunction StyleResolver() {\n  this.loader = new Loader(this.regex);\n}\nStyleResolver.prototype = {\n  regex: /@import\\s+(?:url)?[\"'\\(]*([^'\"\\)]*)['\"\\)]*;/g,\n  // Recursively replace @imports with the text at that url\n  resolve: function(text, url, callback) {\n    var done = function(map) {\n      callback(this.flatten(text, url, map));\n    }.bind(this);\n    this.loader.process(text, url, done);\n  },\n  // resolve the textContent of a style node\n  resolveNode: function(style, callback) {\n    var text = style.textContent;\n    var url = style.ownerDocument.baseURI;\n    var done = function(text) {\n      style.textContent = text;\n      callback(style);\n    };\n    this.resolve(text, url, done);\n  },\n  // flatten all the @imports to text\n  flatten: function(text, base, map) {\n    var matches = this.loader.extractUrls(text, base);\n    var match, url, intermediate;\n    for (var i = 0; i < matches.length; i++) {\n      match = matches[i];\n      url = match.url;\n      // resolve any css text to be relative to the importer\n      intermediate = urlResolver.resolveCssText(map[url], url);\n      // flatten intermediate @imports\n      intermediate = this.flatten(intermediate, url, map);\n      text = text.replace(match.matched, intermediate);\n    }\n    return text;\n  },\n  loadStyles: function(styles, callback) {\n    var loaded=0, l = styles.length;\n    // called in the context of the style\n    function loadedStyle(style) {\n      loaded++;\n      if (loaded === l && callback) {\n        callback();\n      }\n    }\n    for (var i=0, s; (i<l) && (s=styles[i]); i++) {\n      this.resolveNode(s, loadedStyle);\n    }\n  }\n};\n\nvar styleResolver = new StyleResolver();\n\n// exports\nscope.styleResolver = styleResolver;\n\n})(window.Platform);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  scope = scope || {};\n  scope.external = scope.external || {};\n  var target = {\n    shadow: function(inEl) {\n      if (inEl) {\n        return inEl.shadowRoot || inEl.webkitShadowRoot;\n      }\n    },\n    canTarget: function(shadow) {\n      return shadow && Boolean(shadow.elementFromPoint);\n    },\n    targetingShadow: function(inEl) {\n      var s = this.shadow(inEl);\n      if (this.canTarget(s)) {\n        return s;\n      }\n    },\n    olderShadow: function(shadow) {\n      var os = shadow.olderShadowRoot;\n      if (!os) {\n        var se = shadow.querySelector('shadow');\n        if (se) {\n          os = se.olderShadowRoot;\n        }\n      }\n      return os;\n    },\n    allShadows: function(element) {\n      var shadows = [], s = this.shadow(element);\n      while(s) {\n        shadows.push(s);\n        s = this.olderShadow(s);\n      }\n      return shadows;\n    },\n    searchRoot: function(inRoot, x, y) {\n      if (inRoot) {\n        var t = inRoot.elementFromPoint(x, y);\n        var st, sr, os;\n        // is element a shadow host?\n        sr = this.targetingShadow(t);\n        while (sr) {\n          // find the the element inside the shadow root\n          st = sr.elementFromPoint(x, y);\n          if (!st) {\n            // check for older shadows\n            sr = this.olderShadow(sr);\n          } else {\n            // shadowed element may contain a shadow root\n            var ssr = this.targetingShadow(st);\n            return this.searchRoot(ssr, x, y) || st;\n          }\n        }\n        // light dom element is the target\n        return t;\n      }\n    },\n    owner: function(element) {\n      var s = element;\n      // walk up until you hit the shadow root or document\n      while (s.parentNode) {\n        s = s.parentNode;\n      }\n      // the owner element is expected to be a Document or ShadowRoot\n      if (s.nodeType != Node.DOCUMENT_NODE && s.nodeType != Node.DOCUMENT_FRAGMENT_NODE) {\n        s = document;\n      }\n      return s;\n    },\n    findTarget: function(inEvent) {\n      var x = inEvent.clientX, y = inEvent.clientY;\n      // if the listener is in the shadow root, it is much faster to start there\n      var s = this.owner(inEvent.target);\n      // if x, y is not in this root, fall back to document search\n      if (!s.elementFromPoint(x, y)) {\n        s = document;\n      }\n      return this.searchRoot(s, x, y);\n    }\n  };\n  scope.targetFinding = target;\n  scope.findTarget = target.findTarget.bind(target);\n\n  window.PointerEventsPolyfill = scope;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n  function shadowSelector(v) {\n    return 'body ^^ ' + selector(v);\n  }\n  function selector(v) {\n    return '[touch-action=\"' + v + '\"]';\n  }\n  function rule(v) {\n    return '{ -ms-touch-action: ' + v + '; touch-action: ' + v + '; touch-action-delay: none; }';\n  }\n  var attrib2css = [\n    'none',\n    'auto',\n    'pan-x',\n    'pan-y',\n    {\n      rule: 'pan-x pan-y',\n      selectors: [\n        'pan-x pan-y',\n        'pan-y pan-x'\n      ]\n    }\n  ];\n  var styles = '';\n  attrib2css.forEach(function(r) {\n    if (String(r) === r) {\n      styles += selector(r) + rule(r) + '\\n';\n      styles += shadowSelector(r) + rule(r) + '\\n';\n    } else {\n      styles += r.selectors.map(selector) + rule(r.rule) + '\\n';\n      styles += r.selectors.map(shadowSelector) + rule(r.rule) + '\\n';\n    }\n  });\n  var el = document.createElement('style');\n  el.textContent = styles;\n  document.head.appendChild(el);\n})();\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This is the constructor for new PointerEvents.\n *\n * New Pointer Events must be given a type, and an optional dictionary of\n * initialization properties.\n *\n * Due to certain platform requirements, events returned from the constructor\n * identify as MouseEvents.\n *\n * @constructor\n * @param {String} inType The type of the event to create.\n * @param {Object} [inDict] An optional dictionary of initial event properties.\n * @return {Event} A new PointerEvent of type `inType` and initialized with properties from `inDict`.\n */\n(function(scope) {\n  // test for DOM Level 4 Events\n  var NEW_MOUSE_EVENT = false;\n  var HAS_BUTTONS = false;\n  try {\n    var ev = new MouseEvent('click', {buttons: 1});\n    NEW_MOUSE_EVENT = true;\n    HAS_BUTTONS = ev.buttons === 1;\n    ev = null;\n  } catch(e) {\n  }\n\n  var MOUSE_PROPS = [\n    'bubbles',\n    'cancelable',\n    'view',\n    'detail',\n    'screenX',\n    'screenY',\n    'clientX',\n    'clientY',\n    'ctrlKey',\n    'altKey',\n    'shiftKey',\n    'metaKey',\n    'button',\n    'relatedTarget',\n  ];\n\n  var MOUSE_DEFAULTS = [\n    false,\n    false,\n    null,\n    null,\n    0,\n    0,\n    0,\n    0,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null\n  ];\n\n  function PointerEvent(inType, inDict) {\n    inDict = inDict || {};\n    // According to the w3c spec,\n    // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button\n    // MouseEvent.button == 0 can mean either no mouse button depressed, or the\n    // left mouse button depressed.\n    //\n    // As of now, the only way to distinguish between the two states of\n    // MouseEvent.button is by using the deprecated MouseEvent.which property, as\n    // this maps mouse buttons to positive integers > 0, and uses 0 to mean that\n    // no mouse button is held.\n    //\n    // MouseEvent.which is derived from MouseEvent.button at MouseEvent creation,\n    // but initMouseEvent does not expose an argument with which to set\n    // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set\n    // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectations\n    // of app developers.\n    //\n    // The only way to propagate the correct state of MouseEvent.which and\n    // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0\n    // is to call initMouseEvent with a buttonArg value of -1.\n    //\n    // This is fixed with DOM Level 4's use of buttons\n    var buttons = inDict.buttons;\n    // touch has two possible buttons state: 0 and 1, rely on being told the right one\n    if (!HAS_BUTTONS && !buttons && inType !== 'touch') {\n      switch (inDict.which) {\n        case 1: buttons = 1; break;\n        case 2: buttons = 4; break;\n        case 3: buttons = 2; break;\n        default: buttons = 0;\n      }\n    }\n\n    var e;\n    if (NEW_MOUSE_EVENT) {\n      e = new MouseEvent(inType, inDict);\n    } else {\n      e = document.createEvent('MouseEvent');\n\n      // import values from the given dictionary\n      var props = {}, p;\n      for(var i = 0; i < MOUSE_PROPS.length; i++) {\n        p = MOUSE_PROPS[i];\n        props[p] = inDict[p] || MOUSE_DEFAULTS[i];\n      }\n\n      // define the properties inherited from MouseEvent\n      e.initMouseEvent(\n        inType, props.bubbles, props.cancelable, props.view, props.detail,\n        props.screenX, props.screenY, props.clientX, props.clientY, props.ctrlKey,\n        props.altKey, props.shiftKey, props.metaKey, props.button, props.relatedTarget\n      );\n    }\n\n    // make the event pass instanceof checks\n    e.__proto__ = PointerEvent.prototype;\n\n    // define the buttons property according to DOM Level 3 spec\n    if (!HAS_BUTTONS) {\n      // IE 10 has buttons on MouseEvent.prototype as a getter w/o any setting\n      // mechanism\n      Object.defineProperty(e, 'buttons', {get: function(){ return buttons; }, enumerable: true});\n    }\n\n    // Spec requires that pointers without pressure specified use 0.5 for down\n    // state and 0 for up state.\n    var pressure = 0;\n    if (inDict.pressure) {\n      pressure = inDict.pressure;\n    } else {\n      pressure = buttons ? 0.5 : 0;\n    }\n\n    // define the properties of the PointerEvent interface\n    Object.defineProperties(e, {\n      pointerId: { value: inDict.pointerId || 0, enumerable: true },\n      width: { value: inDict.width || 0, enumerable: true },\n      height: { value: inDict.height || 0, enumerable: true },\n      pressure: { value: pressure, enumerable: true },\n      tiltX: { value: inDict.tiltX || 0, enumerable: true },\n      tiltY: { value: inDict.tiltY || 0, enumerable: true },\n      pointerType: { value: inDict.pointerType || '', enumerable: true },\n      hwTimestamp: { value: inDict.hwTimestamp || 0, enumerable: true },\n      isPrimary: { value: inDict.isPrimary || false, enumerable: true }\n    });\n    return e;\n  }\n\n  // PointerEvent extends MouseEvent\n  PointerEvent.prototype = Object.create(MouseEvent.prototype);\n\n  // attach to window\n  if (!scope.PointerEvent) {\n    scope.PointerEvent = PointerEvent;\n  }\n})(window);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module implements an map of pointer states\n */\n(function(scope) {\n  var USE_MAP = window.Map && window.Map.prototype.forEach;\n  var POINTERS_FN = function(){ return this.size; };\n  function PointerMap() {\n    if (USE_MAP) {\n      var m = new Map();\n      m.pointers = POINTERS_FN;\n      return m;\n    } else {\n      this.keys = [];\n      this.values = [];\n    }\n  }\n\n  PointerMap.prototype = {\n    set: function(inId, inEvent) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.values[i] = inEvent;\n      } else {\n        this.keys.push(inId);\n        this.values.push(inEvent);\n      }\n    },\n    has: function(inId) {\n      return this.keys.indexOf(inId) > -1;\n    },\n    'delete': function(inId) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.keys.splice(i, 1);\n        this.values.splice(i, 1);\n      }\n    },\n    get: function(inId) {\n      var i = this.keys.indexOf(inId);\n      return this.values[i];\n    },\n    clear: function() {\n      this.keys.length = 0;\n      this.values.length = 0;\n    },\n    // return value, key, map\n    forEach: function(callback, thisArg) {\n      this.values.forEach(function(v, i) {\n        callback.call(thisArg, v, this.keys[i], this);\n      }, this);\n    },\n    pointers: function() {\n      return this.keys.length;\n    }\n  };\n\n  scope.PointerMap = PointerMap;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var CLONE_PROPS = [\n    // MouseEvent\n    'bubbles',\n    'cancelable',\n    'view',\n    'detail',\n    'screenX',\n    'screenY',\n    'clientX',\n    'clientY',\n    'ctrlKey',\n    'altKey',\n    'shiftKey',\n    'metaKey',\n    'button',\n    'relatedTarget',\n    // DOM Level 3\n    'buttons',\n    // PointerEvent\n    'pointerId',\n    'width',\n    'height',\n    'pressure',\n    'tiltX',\n    'tiltY',\n    'pointerType',\n    'hwTimestamp',\n    'isPrimary',\n    // event instance\n    'type',\n    'target',\n    'currentTarget',\n    'which'\n  ];\n\n  var CLONE_DEFAULTS = [\n    // MouseEvent\n    false,\n    false,\n    null,\n    null,\n    0,\n    0,\n    0,\n    0,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null,\n    // DOM Level 3\n    0,\n    // PointerEvent\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    '',\n    0,\n    false,\n    // event instance\n    '',\n    null,\n    null,\n    0\n  ];\n\n  var HAS_SVG_INSTANCE = (typeof SVGElementInstance !== 'undefined');\n\n  /**\n   * This module is for normalizing events. Mouse and Touch events will be\n   * collected here, and fire PointerEvents that have the same semantics, no\n   * matter the source.\n   * Events fired:\n   *   - pointerdown: a pointing is added\n   *   - pointerup: a pointer is removed\n   *   - pointermove: a pointer is moved\n   *   - pointerover: a pointer crosses into an element\n   *   - pointerout: a pointer leaves an element\n   *   - pointercancel: a pointer will no longer generate events\n   */\n  var dispatcher = {\n    targets: new WeakMap(),\n    handledEvents: new WeakMap(),\n    pointermap: new scope.PointerMap(),\n    eventMap: {},\n    // Scope objects for native events.\n    // This exists for ease of testing.\n    eventSources: {},\n    eventSourceList: [],\n    /**\n     * Add a new event source that will generate pointer events.\n     *\n     * `inSource` must contain an array of event names named `events`, and\n     * functions with the names specified in the `events` array.\n     * @param {string} name A name for the event source\n     * @param {Object} source A new source of platform events.\n     */\n    registerSource: function(name, source) {\n      var s = source;\n      var newEvents = s.events;\n      if (newEvents) {\n        newEvents.forEach(function(e) {\n          if (s[e]) {\n            this.eventMap[e] = s[e].bind(s);\n          }\n        }, this);\n        this.eventSources[name] = s;\n        this.eventSourceList.push(s);\n      }\n    },\n    register: function(element) {\n      var l = this.eventSourceList.length;\n      for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {\n        // call eventsource register\n        es.register.call(es, element);\n      }\n    },\n    unregister: function(element) {\n      var l = this.eventSourceList.length;\n      for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {\n        // call eventsource register\n        es.unregister.call(es, element);\n      }\n    },\n    contains: scope.external.contains || function(container, contained) {\n      return container.contains(contained);\n    },\n    // EVENTS\n    down: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerdown', inEvent);\n    },\n    move: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointermove', inEvent);\n    },\n    up: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerup', inEvent);\n    },\n    enter: function(inEvent) {\n      inEvent.bubbles = false;\n      this.fireEvent('pointerenter', inEvent);\n    },\n    leave: function(inEvent) {\n      inEvent.bubbles = false;\n      this.fireEvent('pointerleave', inEvent);\n    },\n    over: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerover', inEvent);\n    },\n    out: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerout', inEvent);\n    },\n    cancel: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointercancel', inEvent);\n    },\n    leaveOut: function(event) {\n      this.out(event);\n      if (!this.contains(event.target, event.relatedTarget)) {\n        this.leave(event);\n      }\n    },\n    enterOver: function(event) {\n      this.over(event);\n      if (!this.contains(event.target, event.relatedTarget)) {\n        this.enter(event);\n      }\n    },\n    // LISTENER LOGIC\n    eventHandler: function(inEvent) {\n      // This is used to prevent multiple dispatch of pointerevents from\n      // platform events. This can happen when two elements in different scopes\n      // are set up to create pointer events, which is relevant to Shadow DOM.\n      if (this.handledEvents.get(inEvent)) {\n        return;\n      }\n      var type = inEvent.type;\n      var fn = this.eventMap && this.eventMap[type];\n      if (fn) {\n        fn(inEvent);\n      }\n      this.handledEvents.set(inEvent, true);\n    },\n    // set up event listeners\n    listen: function(target, events) {\n      events.forEach(function(e) {\n        this.addEvent(target, e);\n      }, this);\n    },\n    // remove event listeners\n    unlisten: function(target, events) {\n      events.forEach(function(e) {\n        this.removeEvent(target, e);\n      }, this);\n    },\n    addEvent: scope.external.addEvent || function(target, eventName) {\n      target.addEventListener(eventName, this.boundHandler);\n    },\n    removeEvent: scope.external.removeEvent || function(target, eventName) {\n      target.removeEventListener(eventName, this.boundHandler);\n    },\n    // EVENT CREATION AND TRACKING\n    /**\n     * Creates a new Event of type `inType`, based on the information in\n     * `inEvent`.\n     *\n     * @param {string} inType A string representing the type of event to create\n     * @param {Event} inEvent A platform event with a target\n     * @return {Event} A PointerEvent of type `inType`\n     */\n    makeEvent: function(inType, inEvent) {\n      // relatedTarget must be null if pointer is captured\n      if (this.captureInfo) {\n        inEvent.relatedTarget = null;\n      }\n      var e = new PointerEvent(inType, inEvent);\n      if (inEvent.preventDefault) {\n        e.preventDefault = inEvent.preventDefault;\n      }\n      this.targets.set(e, this.targets.get(inEvent) || inEvent.target);\n      return e;\n    },\n    // make and dispatch an event in one call\n    fireEvent: function(inType, inEvent) {\n      var e = this.makeEvent(inType, inEvent);\n      return this.dispatchEvent(e);\n    },\n    /**\n     * Returns a snapshot of inEvent, with writable properties.\n     *\n     * @param {Event} inEvent An event that contains properties to copy.\n     * @return {Object} An object containing shallow copies of `inEvent`'s\n     *    properties.\n     */\n    cloneEvent: function(inEvent) {\n      var eventCopy = {}, p;\n      for (var i = 0; i < CLONE_PROPS.length; i++) {\n        p = CLONE_PROPS[i];\n        eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i];\n        // Work around SVGInstanceElement shadow tree\n        // Return the <use> element that is represented by the instance for Safari, Chrome, IE.\n        // This is the behavior implemented by Firefox.\n        if (HAS_SVG_INSTANCE && (p === 'target' || p === 'relatedTarget')) {\n          if (eventCopy[p] instanceof SVGElementInstance) {\n            eventCopy[p] = eventCopy[p].correspondingUseElement;\n          }\n        }\n      }\n      // keep the semantics of preventDefault\n      if (inEvent.preventDefault) {\n        eventCopy.preventDefault = function() {\n          inEvent.preventDefault();\n        };\n      }\n      return eventCopy;\n    },\n    getTarget: function(inEvent) {\n      // if pointer capture is set, route all events for the specified pointerId\n      // to the capture target\n      if (this.captureInfo) {\n        if (this.captureInfo.id === inEvent.pointerId) {\n          return this.captureInfo.target;\n        }\n      }\n      return this.targets.get(inEvent);\n    },\n    setCapture: function(inPointerId, inTarget) {\n      if (this.captureInfo) {\n        this.releaseCapture(this.captureInfo.id);\n      }\n      this.captureInfo = {id: inPointerId, target: inTarget};\n      var e = new PointerEvent('gotpointercapture', { bubbles: true });\n      this.implicitRelease = this.releaseCapture.bind(this, inPointerId);\n      document.addEventListener('pointerup', this.implicitRelease);\n      document.addEventListener('pointercancel', this.implicitRelease);\n      this.targets.set(e, inTarget);\n      this.asyncDispatchEvent(e);\n    },\n    releaseCapture: function(inPointerId) {\n      if (this.captureInfo && this.captureInfo.id === inPointerId) {\n        var e = new PointerEvent('lostpointercapture', { bubbles: true });\n        var t = this.captureInfo.target;\n        this.captureInfo = null;\n        document.removeEventListener('pointerup', this.implicitRelease);\n        document.removeEventListener('pointercancel', this.implicitRelease);\n        this.targets.set(e, t);\n        this.asyncDispatchEvent(e);\n      }\n    },\n    /**\n     * Dispatches the event to its target.\n     *\n     * @param {Event} inEvent The event to be dispatched.\n     * @return {Boolean} True if an event handler returns true, false otherwise.\n     */\n    dispatchEvent: scope.external.dispatchEvent || function(inEvent) {\n      var t = this.getTarget(inEvent);\n      if (t) {\n        return t.dispatchEvent(inEvent);\n      }\n    },\n    asyncDispatchEvent: function(inEvent) {\n      setTimeout(this.dispatchEvent.bind(this, inEvent), 0);\n    }\n  };\n  dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher);\n  scope.dispatcher = dispatcher;\n  scope.register = dispatcher.register.bind(dispatcher);\n  scope.unregister = dispatcher.unregister.bind(dispatcher);\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module uses Mutation Observers to dynamically adjust which nodes will\n * generate Pointer Events.\n *\n * All nodes that wish to generate Pointer Events must have the attribute\n * `touch-action` set to `none`.\n */\n(function(scope) {\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n  var map = Array.prototype.map.call.bind(Array.prototype.map);\n  var toArray = Array.prototype.slice.call.bind(Array.prototype.slice);\n  var filter = Array.prototype.filter.call.bind(Array.prototype.filter);\n  var MO = window.MutationObserver || window.WebKitMutationObserver;\n  var SELECTOR = '[touch-action]';\n  var OBSERVER_INIT = {\n    subtree: true,\n    childList: true,\n    attributes: true,\n    attributeOldValue: true,\n    attributeFilter: ['touch-action']\n  };\n\n  function Installer(add, remove, changed, binder) {\n    this.addCallback = add.bind(binder);\n    this.removeCallback = remove.bind(binder);\n    this.changedCallback = changed.bind(binder);\n    if (MO) {\n      this.observer = new MO(this.mutationWatcher.bind(this));\n    }\n  }\n\n  Installer.prototype = {\n    watchSubtree: function(target) {\n      // Only watch scopes that can target find, as these are top-level.\n      // Otherwise we can see duplicate additions and removals that add noise.\n      //\n      // TODO(dfreedman): For some instances with ShadowDOMPolyfill, we can see\n      // a removal without an insertion when a node is redistributed among\n      // shadows. Since it all ends up correct in the document, watching only\n      // the document will yield the correct mutations to watch.\n      if (scope.targetFinding.canTarget(target)) {\n        this.observer.observe(target, OBSERVER_INIT);\n      }\n    },\n    enableOnSubtree: function(target) {\n      this.watchSubtree(target);\n      if (target === document && document.readyState !== 'complete') {\n        this.installOnLoad();\n      } else {\n        this.installNewSubtree(target);\n      }\n    },\n    installNewSubtree: function(target) {\n      forEach(this.findElements(target), this.addElement, this);\n    },\n    findElements: function(target) {\n      if (target.querySelectorAll) {\n        return target.querySelectorAll(SELECTOR);\n      }\n      return [];\n    },\n    removeElement: function(el) {\n      this.removeCallback(el);\n    },\n    addElement: function(el) {\n      this.addCallback(el);\n    },\n    elementChanged: function(el, oldValue) {\n      this.changedCallback(el, oldValue);\n    },\n    concatLists: function(accum, list) {\n      return accum.concat(toArray(list));\n    },\n    // register all touch-action = none nodes on document load\n    installOnLoad: function() {\n      document.addEventListener('readystatechange', function() {\n        if (document.readyState === 'complete') {\n          this.installNewSubtree(document);\n        }\n      }.bind(this));\n    },\n    isElement: function(n) {\n      return n.nodeType === Node.ELEMENT_NODE;\n    },\n    flattenMutationTree: function(inNodes) {\n      // find children with touch-action\n      var tree = map(inNodes, this.findElements, this);\n      // make sure the added nodes are accounted for\n      tree.push(filter(inNodes, this.isElement));\n      // flatten the list\n      return tree.reduce(this.concatLists, []);\n    },\n    mutationWatcher: function(mutations) {\n      mutations.forEach(this.mutationHandler, this);\n    },\n    mutationHandler: function(m) {\n      if (m.type === 'childList') {\n        var added = this.flattenMutationTree(m.addedNodes);\n        added.forEach(this.addElement, this);\n        var removed = this.flattenMutationTree(m.removedNodes);\n        removed.forEach(this.removeElement, this);\n      } else if (m.type === 'attributes') {\n        this.elementChanged(m.target, m.oldValue);\n      }\n    }\n  };\n\n  if (!MO) {\n    Installer.prototype.watchSubtree = function(){\n      console.warn('PointerEventsPolyfill: MutationObservers not found, touch-action will not be dynamically detected');\n    };\n  }\n\n  scope.Installer = Installer;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function (scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = dispatcher.pointermap;\n  // radius around touchend that swallows mouse events\n  var DEDUP_DIST = 25;\n\n  // handler block for native mouse events\n  var mouseEvents = {\n    POINTER_ID: 1,\n    POINTER_TYPE: 'mouse',\n    events: [\n      'mousedown',\n      'mousemove',\n      'mouseup',\n      'mouseover',\n      'mouseout'\n    ],\n    register: function(target) {\n      dispatcher.listen(target, this.events);\n    },\n    unregister: function(target) {\n      dispatcher.unlisten(target, this.events);\n    },\n    lastTouches: [],\n    // collide with the global mouse listener\n    isEventSimulatedFromTouch: function(inEvent) {\n      var lts = this.lastTouches;\n      var x = inEvent.clientX, y = inEvent.clientY;\n      for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) {\n        // simulated mouse events will be swallowed near a primary touchend\n        var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n        if (dx <= DEDUP_DIST && dy <= DEDUP_DIST) {\n          return true;\n        }\n      }\n    },\n    prepareEvent: function(inEvent) {\n      var e = dispatcher.cloneEvent(inEvent);\n      // forward mouse preventDefault\n      var pd = e.preventDefault;\n      e.preventDefault = function() {\n        inEvent.preventDefault();\n        pd();\n      };\n      e.pointerId = this.POINTER_ID;\n      e.isPrimary = true;\n      e.pointerType = this.POINTER_TYPE;\n      return e;\n    },\n    mousedown: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var p = pointermap.has(this.POINTER_ID);\n        // TODO(dfreedman) workaround for some elements not sending mouseup\n        // http://crbug/149091\n        if (p) {\n          this.cancel(inEvent);\n        }\n        var e = this.prepareEvent(inEvent);\n        pointermap.set(this.POINTER_ID, inEvent);\n        dispatcher.down(e);\n      }\n    },\n    mousemove: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var e = this.prepareEvent(inEvent);\n        dispatcher.move(e);\n      }\n    },\n    mouseup: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var p = pointermap.get(this.POINTER_ID);\n        if (p && p.button === inEvent.button) {\n          var e = this.prepareEvent(inEvent);\n          dispatcher.up(e);\n          this.cleanupMouse();\n        }\n      }\n    },\n    mouseover: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var e = this.prepareEvent(inEvent);\n        dispatcher.enterOver(e);\n      }\n    },\n    mouseout: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var e = this.prepareEvent(inEvent);\n        dispatcher.leaveOut(e);\n      }\n    },\n    cancel: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.cancel(e);\n      this.cleanupMouse();\n    },\n    cleanupMouse: function() {\n      pointermap['delete'](this.POINTER_ID);\n    }\n  };\n\n  scope.mouseEvents = mouseEvents;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var findTarget = scope.findTarget;\n  var allShadows = scope.targetFinding.allShadows.bind(scope.targetFinding);\n  var pointermap = dispatcher.pointermap;\n  var touchMap = Array.prototype.map.call.bind(Array.prototype.map);\n  // This should be long enough to ignore compat mouse events made by touch\n  var DEDUP_TIMEOUT = 2500;\n  var CLICK_COUNT_TIMEOUT = 200;\n  var ATTRIB = 'touch-action';\n  var INSTALLER;\n  // The presence of touch event handlers blocks scrolling, and so we must be careful to\n  // avoid adding handlers unnecessarily.  Chrome plans to add a touch-action-delay property\n  // (crbug.com/329559) to address this, and once we have that we can opt-in to a simpler\n  // handler registration mechanism.  Rather than try to predict how exactly to opt-in to\n  // that we'll just leave this disabled until there is a build of Chrome to test.\n  var HAS_TOUCH_ACTION_DELAY = false;\n  \n  // handler block for native touch events\n  var touchEvents = {\n    scrollType: new WeakMap(),\n    events: [\n      'touchstart',\n      'touchmove',\n      'touchend',\n      'touchcancel'\n    ],\n    register: function(target) {\n      if (HAS_TOUCH_ACTION_DELAY) {\n        dispatcher.listen(target, this.events);\n      } else {\n        INSTALLER.enableOnSubtree(target);\n      }\n    },\n    unregister: function(target) {\n      if (HAS_TOUCH_ACTION_DELAY) {\n        dispatcher.unlisten(target, this.events);\n      } else {\n        // TODO(dfreedman): is it worth it to disconnect the MO?\n      }\n    },\n    elementAdded: function(el) {\n      var a = el.getAttribute(ATTRIB);\n      var st = this.touchActionToScrollType(a);\n      if (st) {\n        this.scrollType.set(el, st);\n        dispatcher.listen(el, this.events);\n        // set touch-action on shadows as well\n        allShadows(el).forEach(function(s) {\n          this.scrollType.set(s, st);\n          dispatcher.listen(s, this.events);\n        }, this);\n      }\n    },\n    elementRemoved: function(el) {\n      this.scrollType['delete'](el);\n      dispatcher.unlisten(el, this.events);\n      // remove touch-action from shadow\n      allShadows(el).forEach(function(s) {\n        this.scrollType['delete'](s);\n        dispatcher.unlisten(s, this.events);\n      }, this);\n    },\n    elementChanged: function(el, oldValue) {\n      var a = el.getAttribute(ATTRIB);\n      var st = this.touchActionToScrollType(a);\n      var oldSt = this.touchActionToScrollType(oldValue);\n      // simply update scrollType if listeners are already established\n      if (st && oldSt) {\n        this.scrollType.set(el, st);\n        allShadows(el).forEach(function(s) {\n          this.scrollType.set(s, st);\n        }, this);\n      } else if (oldSt) {\n        this.elementRemoved(el);\n      } else if (st) {\n        this.elementAdded(el);\n      }\n    },\n    scrollTypes: {\n      EMITTER: 'none',\n      XSCROLLER: 'pan-x',\n      YSCROLLER: 'pan-y',\n      SCROLLER: /^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/\n    },\n    touchActionToScrollType: function(touchAction) {\n      var t = touchAction;\n      var st = this.scrollTypes;\n      if (t === 'none') {\n        return 'none';\n      } else if (t === st.XSCROLLER) {\n        return 'X';\n      } else if (t === st.YSCROLLER) {\n        return 'Y';\n      } else if (st.SCROLLER.exec(t)) {\n        return 'XY';\n      }\n    },\n    POINTER_TYPE: 'touch',\n    firstTouch: null,\n    isPrimaryTouch: function(inTouch) {\n      return this.firstTouch === inTouch.identifier;\n    },\n    setPrimaryTouch: function(inTouch) {\n      // set primary touch if there no pointers, or the only pointer is the mouse\n      if (pointermap.pointers() === 0 || (pointermap.pointers() === 1 && pointermap.has(1))) {\n        this.firstTouch = inTouch.identifier;\n        this.firstXY = {X: inTouch.clientX, Y: inTouch.clientY};\n        this.scrolling = false;\n        this.cancelResetClickCount();\n      }\n    },\n    removePrimaryPointer: function(inPointer) {\n      if (inPointer.isPrimary) {\n        this.firstTouch = null;\n        this.firstXY = null;\n        this.resetClickCount();\n      }\n    },\n    clickCount: 0,\n    resetId: null,\n    resetClickCount: function() {\n      var fn = function() {\n        this.clickCount = 0;\n        this.resetId = null;\n      }.bind(this);\n      this.resetId = setTimeout(fn, CLICK_COUNT_TIMEOUT);\n    },\n    cancelResetClickCount: function() {\n      if (this.resetId) {\n        clearTimeout(this.resetId);\n      }\n    },\n    typeToButtons: function(type) {\n      var ret = 0;\n      if (type === 'touchstart' || type === 'touchmove') {\n        ret = 1;\n      }\n      return ret;\n    },\n    touchToPointer: function(inTouch) {\n      var e = dispatcher.cloneEvent(inTouch);\n      // Spec specifies that pointerId 1 is reserved for Mouse.\n      // Touch identifiers can start at 0.\n      // Add 2 to the touch identifier for compatibility.\n      e.pointerId = inTouch.identifier + 2;\n      e.target = findTarget(e);\n      e.bubbles = true;\n      e.cancelable = true;\n      e.detail = this.clickCount;\n      e.button = 0;\n      e.buttons = this.typeToButtons(this.currentTouchEvent);\n      e.width = inTouch.webkitRadiusX || inTouch.radiusX || 0;\n      e.height = inTouch.webkitRadiusY || inTouch.radiusY || 0;\n      e.pressure = inTouch.webkitForce || inTouch.force || 0.5;\n      e.isPrimary = this.isPrimaryTouch(inTouch);\n      e.pointerType = this.POINTER_TYPE;\n      return e;\n    },\n    processTouches: function(inEvent, inFunction) {\n      var tl = inEvent.changedTouches;\n      this.currentTouchEvent = inEvent.type;\n      var pointers = touchMap(tl, this.touchToPointer, this);\n      // forward touch preventDefaults\n      pointers.forEach(function(p) {\n        p.preventDefault = function() {\n          this.scrolling = false;\n          this.firstXY = null;\n          inEvent.preventDefault();\n        };\n      }, this);\n      pointers.forEach(inFunction, this);\n    },\n    // For single axis scrollers, determines whether the element should emit\n    // pointer events or behave as a scroller\n    shouldScroll: function(inEvent) {\n      if (this.firstXY) {\n        var ret;\n        var scrollAxis = this.scrollType.get(inEvent.currentTarget);\n        if (scrollAxis === 'none') {\n          // this element is a touch-action: none, should never scroll\n          ret = false;\n        } else if (scrollAxis === 'XY') {\n          // this element should always scroll\n          ret = true;\n        } else {\n          var t = inEvent.changedTouches[0];\n          // check the intended scroll axis, and other axis\n          var a = scrollAxis;\n          var oa = scrollAxis === 'Y' ? 'X' : 'Y';\n          var da = Math.abs(t['client' + a] - this.firstXY[a]);\n          var doa = Math.abs(t['client' + oa] - this.firstXY[oa]);\n          // if delta in the scroll axis > delta other axis, scroll instead of\n          // making events\n          ret = da >= doa;\n        }\n        this.firstXY = null;\n        return ret;\n      }\n    },\n    findTouch: function(inTL, inId) {\n      for (var i = 0, l = inTL.length, t; i < l && (t = inTL[i]); i++) {\n        if (t.identifier === inId) {\n          return true;\n        }\n      }\n    },\n    // In some instances, a touchstart can happen without a touchend. This\n    // leaves the pointermap in a broken state.\n    // Therefore, on every touchstart, we remove the touches that did not fire a\n    // touchend event.\n    // To keep state globally consistent, we fire a\n    // pointercancel for this \"abandoned\" touch\n    vacuumTouches: function(inEvent) {\n      var tl = inEvent.touches;\n      // pointermap.pointers() should be < tl.length here, as the touchstart has not\n      // been processed yet.\n      if (pointermap.pointers() >= tl.length) {\n        var d = [];\n        pointermap.forEach(function(value, key) {\n          // Never remove pointerId == 1, which is mouse.\n          // Touch identifiers are 2 smaller than their pointerId, which is the\n          // index in pointermap.\n          if (key !== 1 && !this.findTouch(tl, key - 2)) {\n            var p = value.out;\n            d.push(this.touchToPointer(p));\n          }\n        }, this);\n        d.forEach(this.cancelOut, this);\n      }\n    },\n    touchstart: function(inEvent) {\n      this.vacuumTouches(inEvent);\n      this.setPrimaryTouch(inEvent.changedTouches[0]);\n      this.dedupSynthMouse(inEvent);\n      if (!this.scrolling) {\n        this.clickCount++;\n        this.processTouches(inEvent, this.overDown);\n      }\n    },\n    overDown: function(inPointer) {\n      var p = pointermap.set(inPointer.pointerId, {\n        target: inPointer.target,\n        out: inPointer,\n        outTarget: inPointer.target\n      });\n      dispatcher.over(inPointer);\n      dispatcher.enter(inPointer);\n      dispatcher.down(inPointer);\n    },\n    touchmove: function(inEvent) {\n      if (!this.scrolling) {\n        if (this.shouldScroll(inEvent)) {\n          this.scrolling = true;\n          this.touchcancel(inEvent);\n        } else {\n          inEvent.preventDefault();\n          this.processTouches(inEvent, this.moveOverOut);\n        }\n      }\n    },\n    moveOverOut: function(inPointer) {\n      var event = inPointer;\n      var pointer = pointermap.get(event.pointerId);\n      // a finger drifted off the screen, ignore it\n      if (!pointer) {\n        return;\n      }\n      var outEvent = pointer.out;\n      var outTarget = pointer.outTarget;\n      dispatcher.move(event);\n      if (outEvent && outTarget !== event.target) {\n        outEvent.relatedTarget = event.target;\n        event.relatedTarget = outTarget;\n        // recover from retargeting by shadow\n        outEvent.target = outTarget;\n        if (event.target) {\n          dispatcher.leaveOut(outEvent);\n          dispatcher.enterOver(event);\n        } else {\n          // clean up case when finger leaves the screen\n          event.target = outTarget;\n          event.relatedTarget = null;\n          this.cancelOut(event);\n        }\n      }\n      pointer.out = event;\n      pointer.outTarget = event.target;\n    },\n    touchend: function(inEvent) {\n      this.dedupSynthMouse(inEvent);\n      this.processTouches(inEvent, this.upOut);\n    },\n    upOut: function(inPointer) {\n      if (!this.scrolling) {\n        dispatcher.up(inPointer);\n        dispatcher.out(inPointer);\n        dispatcher.leave(inPointer);\n      }\n      this.cleanUpPointer(inPointer);\n    },\n    touchcancel: function(inEvent) {\n      this.processTouches(inEvent, this.cancelOut);\n    },\n    cancelOut: function(inPointer) {\n      dispatcher.cancel(inPointer);\n      dispatcher.out(inPointer);\n      dispatcher.leave(inPointer);\n      this.cleanUpPointer(inPointer);\n    },\n    cleanUpPointer: function(inPointer) {\n      pointermap['delete'](inPointer.pointerId);\n      this.removePrimaryPointer(inPointer);\n    },\n    // prevent synth mouse events from creating pointer events\n    dedupSynthMouse: function(inEvent) {\n      var lts = scope.mouseEvents.lastTouches;\n      var t = inEvent.changedTouches[0];\n      // only the primary finger will synth mouse events\n      if (this.isPrimaryTouch(t)) {\n        // remember x/y of last touch\n        var lt = {x: t.clientX, y: t.clientY};\n        lts.push(lt);\n        var fn = (function(lts, lt){\n          var i = lts.indexOf(lt);\n          if (i > -1) {\n            lts.splice(i, 1);\n          }\n        }).bind(null, lts, lt);\n        setTimeout(fn, DEDUP_TIMEOUT);\n      }\n    }\n  };\n\n  if (!HAS_TOUCH_ACTION_DELAY) {\n    INSTALLER = new scope.Installer(touchEvents.elementAdded, touchEvents.elementRemoved, touchEvents.elementChanged, touchEvents);\n  }\n\n  scope.touchEvents = touchEvents;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = dispatcher.pointermap;\n  var HAS_BITMAP_TYPE = window.MSPointerEvent && typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE === 'number';\n  var msEvents = {\n    events: [\n      'MSPointerDown',\n      'MSPointerMove',\n      'MSPointerUp',\n      'MSPointerOut',\n      'MSPointerOver',\n      'MSPointerCancel',\n      'MSGotPointerCapture',\n      'MSLostPointerCapture'\n    ],\n    register: function(target) {\n      dispatcher.listen(target, this.events);\n    },\n    unregister: function(target) {\n      dispatcher.unlisten(target, this.events);\n    },\n    POINTER_TYPES: [\n      '',\n      'unavailable',\n      'touch',\n      'pen',\n      'mouse'\n    ],\n    prepareEvent: function(inEvent) {\n      var e = inEvent;\n      if (HAS_BITMAP_TYPE) {\n        e = dispatcher.cloneEvent(inEvent);\n        e.pointerType = this.POINTER_TYPES[inEvent.pointerType];\n      }\n      return e;\n    },\n    cleanup: function(id) {\n      pointermap['delete'](id);\n    },\n    MSPointerDown: function(inEvent) {\n      pointermap.set(inEvent.pointerId, inEvent);\n      var e = this.prepareEvent(inEvent);\n      dispatcher.down(e);\n    },\n    MSPointerMove: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.move(e);\n    },\n    MSPointerUp: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.up(e);\n      this.cleanup(inEvent.pointerId);\n    },\n    MSPointerOut: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.leaveOut(e);\n    },\n    MSPointerOver: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.enterOver(e);\n    },\n    MSPointerCancel: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.cancel(e);\n      this.cleanup(inEvent.pointerId);\n    },\n    MSLostPointerCapture: function(inEvent) {\n      var e = dispatcher.makeEvent('lostpointercapture', inEvent);\n      dispatcher.dispatchEvent(e);\n    },\n    MSGotPointerCapture: function(inEvent) {\n      var e = dispatcher.makeEvent('gotpointercapture', inEvent);\n      dispatcher.dispatchEvent(e);\n    }\n  };\n\n  scope.msEvents = msEvents;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module contains the handlers for native platform events.\n * From here, the dispatcher is called to create unified pointer events.\n * Included are touch events (v1), mouse events, and MSPointerEvents.\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n\n  // only activate if this platform does not have pointer events\n  if (window.navigator.pointerEnabled === undefined) {\n    Object.defineProperty(window.navigator, 'pointerEnabled', {value: true, enumerable: true});\n\n    if (window.navigator.msPointerEnabled) {\n      var tp = window.navigator.msMaxTouchPoints;\n      Object.defineProperty(window.navigator, 'maxTouchPoints', {\n        value: tp,\n        enumerable: true\n      });\n      dispatcher.registerSource('ms', scope.msEvents);\n    } else {\n      dispatcher.registerSource('mouse', scope.mouseEvents);\n      if (window.ontouchstart !== undefined) {\n        dispatcher.registerSource('touch', scope.touchEvents);\n      }\n    }\n\n    dispatcher.register(document);\n  }\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var n = window.navigator;\n  var s, r;\n  function assertDown(id) {\n    if (!dispatcher.pointermap.has(id)) {\n      throw new Error('InvalidPointerId');\n    }\n  }\n  if (n.msPointerEnabled) {\n    s = function(pointerId) {\n      assertDown(pointerId);\n      this.msSetPointerCapture(pointerId);\n    };\n    r = function(pointerId) {\n      assertDown(pointerId);\n      this.msReleasePointerCapture(pointerId);\n    };\n  } else {\n    s = function setPointerCapture(pointerId) {\n      assertDown(pointerId);\n      dispatcher.setCapture(pointerId, this);\n    };\n    r = function releasePointerCapture(pointerId) {\n      assertDown(pointerId);\n      dispatcher.releaseCapture(pointerId, this);\n    };\n  }\n  if (window.Element && !Element.prototype.setPointerCapture) {\n    Object.defineProperties(Element.prototype, {\n      'setPointerCapture': {\n        value: s\n      },\n      'releasePointerCapture': {\n        value: r\n      }\n    });\n  }\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  /**\n   * This class contains the gesture recognizers that create the PointerGesture\n   * events.\n   *\n   * @class PointerGestures\n   * @static\n   */\n  scope = scope || {};\n  scope.utils = {\n    LCA: {\n      // Determines the lowest node in the ancestor chain of a and b\n      find: function(a, b) {\n        if (a === b) {\n          return a;\n        }\n        // fast case, a is a direct descendant of b or vice versa\n        if (a.contains) {\n          if (a.contains(b)) {\n            return a;\n          }\n          if (b.contains(a)) {\n            return b;\n          }\n        }\n        var adepth = this.depth(a);\n        var bdepth = this.depth(b);\n        var d = adepth - bdepth;\n        if (d > 0) {\n          a = this.walk(a, d);\n        } else {\n          b = this.walk(b, -d);\n        }\n        while(a && b && a !== b) {\n          a = this.walk(a, 1);\n          b = this.walk(b, 1);\n        }\n        return a;\n      },\n      walk: function(n, u) {\n        for (var i = 0; i < u; i++) {\n          n = n.parentNode;\n        }\n        return n;\n      },\n      depth: function(n) {\n        var d = 0;\n        while(n) {\n          d++;\n          n = n.parentNode;\n        }\n        return d;\n      }\n    }\n  };\n  scope.findLCA = function(a, b) {\n    return scope.utils.LCA.find(a, b);\n  }\n  window.PointerGestures = scope;\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module implements an map of pointer states\n */\n(function(scope) {\n  var USE_MAP = window.Map && window.Map.prototype.forEach;\n  var POINTERS_FN = function(){ return this.size; };\n  function PointerMap() {\n    if (USE_MAP) {\n      var m = new Map();\n      m.pointers = POINTERS_FN;\n      return m;\n    } else {\n      this.keys = [];\n      this.values = [];\n    }\n  }\n\n  PointerMap.prototype = {\n    set: function(inId, inEvent) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.values[i] = inEvent;\n      } else {\n        this.keys.push(inId);\n        this.values.push(inEvent);\n      }\n    },\n    has: function(inId) {\n      return this.keys.indexOf(inId) > -1;\n    },\n    'delete': function(inId) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.keys.splice(i, 1);\n        this.values.splice(i, 1);\n      }\n    },\n    get: function(inId) {\n      var i = this.keys.indexOf(inId);\n      return this.values[i];\n    },\n    clear: function() {\n      this.keys.length = 0;\n      this.values.length = 0;\n    },\n    // return value, key, map\n    forEach: function(callback, thisArg) {\n      this.values.forEach(function(v, i) {\n        callback.call(thisArg, v, this.keys[i], this);\n      }, this);\n    },\n    pointers: function() {\n      return this.keys.length;\n    }\n  };\n\n  scope.PointerMap = PointerMap;\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var CLONE_PROPS = [\n    // MouseEvent\n    'bubbles',\n    'cancelable',\n    'view',\n    'detail',\n    'screenX',\n    'screenY',\n    'clientX',\n    'clientY',\n    'ctrlKey',\n    'altKey',\n    'shiftKey',\n    'metaKey',\n    'button',\n    'relatedTarget',\n    // DOM Level 3\n    'buttons',\n    // PointerEvent\n    'pointerId',\n    'width',\n    'height',\n    'pressure',\n    'tiltX',\n    'tiltY',\n    'pointerType',\n    'hwTimestamp',\n    'isPrimary',\n    // event instance\n    'type',\n    'target',\n    'currentTarget',\n    'screenX',\n    'screenY',\n    'pageX',\n    'pageY',\n    'tapPrevented'\n  ];\n\n  var CLONE_DEFAULTS = [\n    // MouseEvent\n    false,\n    false,\n    null,\n    null,\n    0,\n    0,\n    0,\n    0,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null,\n    // DOM Level 3\n    0,\n    // PointerEvent\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    '',\n    0,\n    false,\n    // event instance\n    '',\n    null,\n    null,\n    0,\n    0,\n    0,\n    0\n  ];\n\n  var dispatcher = {\n    handledEvents: new WeakMap(),\n    targets: new WeakMap(),\n    handlers: {},\n    recognizers: {},\n    events: {},\n    // Add a new gesture recognizer to the event listeners.\n    // Recognizer needs an `events` property.\n    registerRecognizer: function(inName, inRecognizer) {\n      var r = inRecognizer;\n      this.recognizers[inName] = r;\n      r.events.forEach(function(e) {\n        if (r[e]) {\n          this.events[e] = true;\n          var f = r[e].bind(r);\n          this.addHandler(e, f);\n        }\n      }, this);\n    },\n    addHandler: function(inEvent, inFn) {\n      var e = inEvent;\n      if (!this.handlers[e]) {\n        this.handlers[e] = [];\n      }\n      this.handlers[e].push(inFn);\n    },\n    // add event listeners for inTarget\n    registerTarget: function(inTarget) {\n      this.listen(Object.keys(this.events), inTarget);\n    },\n    // remove event listeners for inTarget\n    unregisterTarget: function(inTarget) {\n      this.unlisten(Object.keys(this.events), inTarget);\n    },\n    // LISTENER LOGIC\n    eventHandler: function(inEvent) {\n      if (this.handledEvents.get(inEvent)) {\n        return;\n      }\n      var type = inEvent.type, fns = this.handlers[type];\n      if (fns) {\n        this.makeQueue(fns, inEvent);\n      }\n      this.handledEvents.set(inEvent, true);\n    },\n    // queue event for async dispatch\n    makeQueue: function(inHandlerFns, inEvent) {\n      // must clone events to keep the (possibly shadowed) target correct for\n      // async dispatching\n      var e = this.cloneEvent(inEvent);\n      setTimeout(this.runQueue.bind(this, inHandlerFns, e), 0);\n    },\n    // Dispatch the queued events\n    runQueue: function(inHandlers, inEvent) {\n      this.currentPointerId = inEvent.pointerId;\n      for (var i = 0, f, l = inHandlers.length; (i < l) && (f = inHandlers[i]); i++) {\n        f(inEvent);\n      }\n      this.currentPointerId = 0;\n    },\n    // set up event listeners\n    listen: function(inEvents, inTarget) {\n      inEvents.forEach(function(e) {\n        this.addEvent(e, this.boundHandler, false, inTarget);\n      }, this);\n    },\n    // remove event listeners\n    unlisten: function(inEvents) {\n      inEvents.forEach(function(e) {\n        this.removeEvent(e, this.boundHandler, false, inTarget);\n      }, this);\n    },\n    addEvent: function(inEventName, inEventHandler, inCapture, inTarget) {\n      inTarget.addEventListener(inEventName, inEventHandler, inCapture);\n    },\n    removeEvent: function(inEventName, inEventHandler, inCapture, inTarget) {\n      inTarget.removeEventListener(inEventName, inEventHandler, inCapture);\n    },\n    // EVENT CREATION AND TRACKING\n    // Creates a new Event of type `inType`, based on the information in\n    // `inEvent`.\n    makeEvent: function(inType, inDict) {\n      return new PointerGestureEvent(inType, inDict);\n    },\n    /*\n     * Returns a snapshot of inEvent, with writable properties.\n     *\n     * @method cloneEvent\n     * @param {Event} inEvent An event that contains properties to copy.\n     * @return {Object} An object containing shallow copies of `inEvent`'s\n     *    properties.\n     */\n    cloneEvent: function(inEvent) {\n      var eventCopy = {}, p;\n      for (var i = 0; i < CLONE_PROPS.length; i++) {\n        p = CLONE_PROPS[i];\n        eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i];\n      }\n      return eventCopy;\n    },\n    // Dispatches the event to its target.\n    dispatchEvent: function(inEvent, inTarget) {\n      var t = inTarget || this.targets.get(inEvent);\n      if (t) {\n        t.dispatchEvent(inEvent);\n        if (inEvent.tapPrevented) {\n          this.preventTap(this.currentPointerId);\n        }\n      }\n    },\n    asyncDispatchEvent: function(inEvent, inTarget) {\n      var fn = function() {\n        this.dispatchEvent(inEvent, inTarget);\n      }.bind(this);\n      setTimeout(fn, 0);\n    },\n    preventTap: function(inPointerId) {\n      var t = this.recognizers.tap;\n      if (t){\n        t.preventTap(inPointerId);\n      }\n    }\n  };\n  dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher);\n  // recognizers call into the dispatcher and load later\n  // solve the chicken and egg problem by having registerScopes module run last\n  dispatcher.registerQueue = [];\n  dispatcher.immediateRegister = false;\n  scope.dispatcher = dispatcher;\n  /**\n   * Enable gesture events for a given scope, typically\n   * [ShadowRoots](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-root-object).\n   *\n   * @for PointerGestures\n   * @method register\n   * @param {ShadowRoot} scope A top level scope to enable gesture\n   * support on.\n   */\n  scope.register = function(inScope) {\n    if (dispatcher.immediateRegister) {\n      var pe = window.PointerEventsPolyfill;\n      if (pe) {\n        pe.register(inScope);\n      }\n      scope.dispatcher.registerTarget(inScope);\n    } else {\n      dispatcher.registerQueue.push(inScope);\n    }\n  };\n  scope.register(document);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event is fired when a pointer is held down for 200ms.\n *\n * @module PointerGestures\n * @submodule Events\n * @class hold\n */\n/**\n * Type of pointer that made the holding event.\n * @type String\n * @property pointerType\n */\n/**\n * Screen X axis position of the held pointer\n * @type Number\n * @property clientX\n */\n/**\n * Screen Y axis position of the held pointer\n * @type Number\n * @property clientY\n */\n/**\n * Type of pointer that made the holding event.\n * @type String\n * @property pointerType\n */\n/**\n * This event is fired every 200ms while a pointer is held down.\n *\n * @class holdpulse\n * @extends hold\n */\n/**\n * Milliseconds pointer has been held down.\n * @type Number\n * @property holdTime\n */\n/**\n * This event is fired when a held pointer is released or moved.\n *\n * @class released\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var hold = {\n    // wait at least HOLD_DELAY ms between hold and pulse events\n    HOLD_DELAY: 200,\n    // pointer can move WIGGLE_THRESHOLD pixels before not counting as a hold\n    WIGGLE_THRESHOLD: 16,\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel'\n    ],\n    heldPointer: null,\n    holdJob: null,\n    pulse: function() {\n      var hold = Date.now() - this.heldPointer.timeStamp;\n      var type = this.held ? 'holdpulse' : 'hold';\n      this.fireHold(type, hold);\n      this.held = true;\n    },\n    cancel: function() {\n      clearInterval(this.holdJob);\n      if (this.held) {\n        this.fireHold('release');\n      }\n      this.held = false;\n      this.heldPointer = null;\n      this.target = null;\n      this.holdJob = null;\n    },\n    pointerdown: function(inEvent) {\n      if (inEvent.isPrimary && !this.heldPointer) {\n        this.heldPointer = inEvent;\n        this.target = inEvent.target;\n        this.holdJob = setInterval(this.pulse.bind(this), this.HOLD_DELAY);\n      }\n    },\n    pointerup: function(inEvent) {\n      if (this.heldPointer && this.heldPointer.pointerId === inEvent.pointerId) {\n        this.cancel();\n      }\n    },\n    pointercancel: function(inEvent) {\n      this.cancel();\n    },\n    pointermove: function(inEvent) {\n      if (this.heldPointer && this.heldPointer.pointerId === inEvent.pointerId) {\n        var x = inEvent.clientX - this.heldPointer.clientX;\n        var y = inEvent.clientY - this.heldPointer.clientY;\n        if ((x * x + y * y) > this.WIGGLE_THRESHOLD) {\n          this.cancel();\n        }\n      }\n    },\n    fireHold: function(inType, inHoldTime) {\n      var p = {\n        pointerType: this.heldPointer.pointerType,\n        clientX: this.heldPointer.clientX,\n        clientY: this.heldPointer.clientY\n      };\n      if (inHoldTime) {\n        p.holdTime = inHoldTime;\n      }\n      var e = dispatcher.makeEvent(inType, p);\n      dispatcher.dispatchEvent(e, this.target);\n      if (e.tapPrevented) {\n        dispatcher.preventTap(this.heldPointer.pointerId);\n      }\n    }\n  };\n  dispatcher.registerRecognizer('hold', hold);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event denotes the beginning of a series of tracking events.\n *\n * @module PointerGestures\n * @submodule Events\n * @class trackstart\n */\n/**\n * Pixels moved in the x direction since trackstart.\n * @type Number\n * @property dx\n */\n/**\n * Pixes moved in the y direction since trackstart.\n * @type Number\n * @property dy\n */\n/**\n * Pixels moved in the x direction since the last track.\n * @type Number\n * @property ddx\n */\n/**\n * Pixles moved in the y direction since the last track.\n * @type Number\n * @property ddy\n */\n/**\n * The clientX position of the track gesture.\n * @type Number\n * @property clientX\n */\n/**\n * The clientY position of the track gesture.\n * @type Number\n * @property clientY\n */\n/**\n * The pageX position of the track gesture.\n * @type Number\n * @property pageX\n */\n/**\n * The pageY position of the track gesture.\n * @type Number\n * @property pageY\n */\n/**\n * The screenX position of the track gesture.\n * @type Number\n * @property screenX\n */\n/**\n * The screenY position of the track gesture.\n * @type Number\n * @property screenY\n */\n/**\n * The last x axis direction of the pointer.\n * @type Number\n * @property xDirection\n */\n/**\n * The last y axis direction of the pointer.\n * @type Number\n * @property yDirection\n */\n/**\n * A shared object between all tracking events.\n * @type Object\n * @property trackInfo\n */\n/**\n * The element currently under the pointer.\n * @type Element\n * @property relatedTarget\n */\n/**\n * The type of pointer that make the track gesture.\n * @type String\n * @property pointerType\n */\n/**\n *\n * This event fires for all pointer movement being tracked.\n *\n * @class track\n * @extends trackstart\n */\n/**\n * This event fires when the pointer is no longer being tracked.\n *\n * @class trackend\n * @extends trackstart\n */\n\n (function(scope) {\n   var dispatcher = scope.dispatcher;\n   var pointermap = new scope.PointerMap();\n   var track = {\n     events: [\n       'pointerdown',\n       'pointermove',\n       'pointerup',\n       'pointercancel'\n     ],\n     WIGGLE_THRESHOLD: 4,\n     clampDir: function(inDelta) {\n       return inDelta > 0 ? 1 : -1;\n     },\n     calcPositionDelta: function(inA, inB) {\n       var x = 0, y = 0;\n       if (inA && inB) {\n         x = inB.pageX - inA.pageX;\n         y = inB.pageY - inA.pageY;\n       }\n       return {x: x, y: y};\n     },\n     fireTrack: function(inType, inEvent, inTrackingData) {\n       var t = inTrackingData;\n       var d = this.calcPositionDelta(t.downEvent, inEvent);\n       var dd = this.calcPositionDelta(t.lastMoveEvent, inEvent);\n       if (dd.x) {\n         t.xDirection = this.clampDir(dd.x);\n       }\n       if (dd.y) {\n         t.yDirection = this.clampDir(dd.y);\n       }\n       var trackData = {\n         dx: d.x,\n         dy: d.y,\n         ddx: dd.x,\n         ddy: dd.y,\n         clientX: inEvent.clientX,\n         clientY: inEvent.clientY,\n         pageX: inEvent.pageX,\n         pageY: inEvent.pageY,\n         screenX: inEvent.screenX,\n         screenY: inEvent.screenY,\n         xDirection: t.xDirection,\n         yDirection: t.yDirection,\n         trackInfo: t.trackInfo,\n         relatedTarget: inEvent.target,\n         pointerType: inEvent.pointerType\n       };\n       var e = dispatcher.makeEvent(inType, trackData);\n       t.lastMoveEvent = inEvent;\n       dispatcher.dispatchEvent(e, t.downTarget);\n     },\n     pointerdown: function(inEvent) {\n       if (inEvent.isPrimary && (inEvent.pointerType === 'mouse' ? inEvent.buttons === 1 : true)) {\n         var p = {\n           downEvent: inEvent,\n           downTarget: inEvent.target,\n           trackInfo: {},\n           lastMoveEvent: null,\n           xDirection: 0,\n           yDirection: 0,\n           tracking: false\n         };\n         pointermap.set(inEvent.pointerId, p);\n       }\n     },\n     pointermove: function(inEvent) {\n       var p = pointermap.get(inEvent.pointerId);\n       if (p) {\n         if (!p.tracking) {\n           var d = this.calcPositionDelta(p.downEvent, inEvent);\n           var move = d.x * d.x + d.y * d.y;\n           // start tracking only if finger moves more than WIGGLE_THRESHOLD\n           if (move > this.WIGGLE_THRESHOLD) {\n             p.tracking = true;\n             this.fireTrack('trackstart', p.downEvent, p);\n             this.fireTrack('track', inEvent, p);\n           }\n         } else {\n           this.fireTrack('track', inEvent, p);\n         }\n       }\n     },\n     pointerup: function(inEvent) {\n       var p = pointermap.get(inEvent.pointerId);\n       if (p) {\n         if (p.tracking) {\n           this.fireTrack('trackend', inEvent, p);\n         }\n         pointermap.delete(inEvent.pointerId);\n       }\n     },\n     pointercancel: function(inEvent) {\n       this.pointerup(inEvent);\n     }\n   };\n   dispatcher.registerRecognizer('track', track);\n })(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event denotes a rapid down/move/up sequence from a pointer.\n *\n * The event is sent to the first element the pointer went down on.\n *\n * @module PointerGestures\n * @submodule Events\n * @class flick\n */\n/**\n * Signed velocity of the flick in the x direction.\n * @property xVelocity\n * @type Number\n */\n/**\n * Signed velocity of the flick in the y direction.\n * @type Number\n * @property yVelocity\n */\n/**\n * Unsigned total velocity of the flick.\n * @type Number\n * @property velocity\n */\n/**\n * Angle of the flick in degrees, with 0 along the\n * positive x axis.\n * @type Number\n * @property angle\n */\n/**\n * Axis with the greatest absolute velocity. Denoted\n * with 'x' or 'y'.\n * @type String\n * @property majorAxis\n */\n/**\n * Type of the pointer that made the flick.\n * @type String\n * @property pointerType\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var flick = {\n    // TODO(dfreedman): value should be low enough for low speed flicks, but\n    // high enough to remove accidental flicks\n    MIN_VELOCITY: 0.5 /* px/ms */,\n    MAX_QUEUE: 4,\n    moveQueue: [],\n    target: null,\n    pointerId: null,\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel'\n    ],\n    pointerdown: function(inEvent) {\n      if (inEvent.isPrimary && !this.pointerId) {\n        this.pointerId = inEvent.pointerId;\n        this.target = inEvent.target;\n        this.addMove(inEvent);\n      }\n    },\n    pointermove: function(inEvent) {\n      if (inEvent.pointerId === this.pointerId) {\n        this.addMove(inEvent);\n      }\n    },\n    pointerup: function(inEvent) {\n      if (inEvent.pointerId === this.pointerId) {\n        this.fireFlick(inEvent);\n      }\n      this.cleanup();\n    },\n    pointercancel: function(inEvent) {\n      this.cleanup();\n    },\n    cleanup: function() {\n      this.moveQueue = [];\n      this.target = null;\n      this.pointerId = null;\n    },\n    addMove: function(inEvent) {\n      if (this.moveQueue.length >= this.MAX_QUEUE) {\n        this.moveQueue.shift();\n      }\n      this.moveQueue.push(inEvent);\n    },\n    fireFlick: function(inEvent) {\n      var e = inEvent;\n      var l = this.moveQueue.length;\n      var dt, dx, dy, tx, ty, tv, x = 0, y = 0, v = 0;\n      // flick based off the fastest segment of movement\n      for (var i = 0, m; i < l && (m = this.moveQueue[i]); i++) {\n        dt = e.timeStamp - m.timeStamp;\n        dx = e.clientX - m.clientX, dy = e.clientY - m.clientY;\n        tx = dx / dt, ty = dy / dt, tv = Math.sqrt(tx * tx + ty * ty);\n        if (tv > v) {\n          x = tx, y = ty, v = tv;\n        }\n      }\n      var ma = Math.abs(x) > Math.abs(y) ? 'x' : 'y';\n      var a = this.calcAngle(x, y);\n      if (Math.abs(v) >= this.MIN_VELOCITY) {\n        var ev = dispatcher.makeEvent('flick', {\n          xVelocity: x,\n          yVelocity: y,\n          velocity: v,\n          angle: a,\n          majorAxis: ma,\n          pointerType: inEvent.pointerType\n        });\n        dispatcher.dispatchEvent(ev, this.target);\n      }\n    },\n    calcAngle: function(inX, inY) {\n      return (Math.atan2(inY, inX) * 180 / Math.PI);\n    }\n  };\n  dispatcher.registerRecognizer('flick', flick);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/*\n * Basic strategy: find the farthest apart points, use as diameter of circle\n * react to size change and rotation of the chord\n */\n\n/**\n * @module PointerGestures\n * @submodule Events\n * @class pinch\n */\n/**\n * Scale of the pinch zoom gesture\n * @property scale\n * @type Number\n */\n/**\n * Center X position of pointers causing pinch\n * @property centerX\n * @type Number\n */\n/**\n * Center Y position of pointers causing pinch\n * @property centerY\n * @type Number\n */\n\n/**\n * @module PointerGestures\n * @submodule Events\n * @class rotate\n */\n/**\n * Angle (in degrees) of rotation. Measured from starting positions of pointers.\n * @property angle\n * @type Number\n */\n/**\n * Center X position of pointers causing rotation\n * @property centerX\n * @type Number\n */\n/**\n * Center Y position of pointers causing rotation\n * @property centerY\n * @type Number\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = new scope.PointerMap();\n  var RAD_TO_DEG = 180 / Math.PI;\n  var pinch = {\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel'\n    ],\n    reference: {},\n    pointerdown: function(ev) {\n      pointermap.set(ev.pointerId, ev);\n      if (pointermap.pointers() == 2) {\n        var points = this.calcChord();\n        var angle = this.calcAngle(points);\n        this.reference = {\n          angle: angle,\n          diameter: points.diameter,\n          target: scope.findLCA(points.a.target, points.b.target)\n        };\n      }\n    },\n    pointerup: function(ev) {\n      pointermap.delete(ev.pointerId);\n    },\n    pointermove: function(ev) {\n      if (pointermap.has(ev.pointerId)) {\n        pointermap.set(ev.pointerId, ev);\n        if (pointermap.pointers() > 1) {\n          this.calcPinchRotate();\n        }\n      }\n    },\n    pointercancel: function(ev) {\n      this.pointerup(ev);\n    },\n    dispatchPinch: function(diameter, points) {\n      var zoom = diameter / this.reference.diameter;\n      var ev = dispatcher.makeEvent('pinch', {\n        scale: zoom,\n        centerX: points.center.x,\n        centerY: points.center.y\n      });\n      dispatcher.dispatchEvent(ev, this.reference.target);\n    },\n    dispatchRotate: function(angle, points) {\n      var diff = Math.round((angle - this.reference.angle) % 360);\n      var ev = dispatcher.makeEvent('rotate', {\n        angle: diff,\n        centerX: points.center.x,\n        centerY: points.center.y\n      });\n      dispatcher.dispatchEvent(ev, this.reference.target);\n    },\n    calcPinchRotate: function() {\n      var points = this.calcChord();\n      var diameter = points.diameter;\n      var angle = this.calcAngle(points);\n      if (diameter != this.reference.diameter) {\n        this.dispatchPinch(diameter, points);\n      }\n      if (angle != this.reference.angle) {\n        this.dispatchRotate(angle, points);\n      }\n    },\n    calcChord: function() {\n      var pointers = [];\n      pointermap.forEach(function(p) {\n        pointers.push(p);\n      });\n      var dist = 0;\n      // start with at least two pointers\n      var points = {a: pointers[0], b: pointers[1]};\n      var x, y, d;\n      for (var i = 0; i < pointers.length; i++) {\n        var a = pointers[i];\n        for (var j = i + 1; j < pointers.length; j++) {\n          var b = pointers[j];\n          x = Math.abs(a.clientX - b.clientX);\n          y = Math.abs(a.clientY - b.clientY);\n          d = x + y;\n          if (d > dist) {\n            dist = d;\n            points = {a: a, b: b};\n          }\n        }\n      }\n      x = Math.abs(points.a.clientX + points.b.clientX) / 2;\n      y = Math.abs(points.a.clientY + points.b.clientY) / 2;\n      points.center = { x: x, y: y };\n      points.diameter = dist;\n      return points;\n    },\n    calcAngle: function(points) {\n      var x = points.a.clientX - points.b.clientX;\n      var y = points.a.clientY - points.b.clientY;\n      return (360 + Math.atan2(y, x) * RAD_TO_DEG) % 360;\n    },\n  };\n  dispatcher.registerRecognizer('pinch', pinch);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event is fired when a pointer quickly goes down and up, and is used to\n * denote activation.\n *\n * Any gesture event can prevent the tap event from being created by calling\n * `event.preventTap`.\n *\n * Any pointer event can prevent the tap by setting the `tapPrevented` property\n * on itself.\n *\n * @module PointerGestures\n * @submodule Events\n * @class tap\n */\n/**\n * X axis position of the tap.\n * @property x\n * @type Number\n */\n/**\n * Y axis position of the tap.\n * @property y\n * @type Number\n */\n/**\n * Type of the pointer that made the tap.\n * @property pointerType\n * @type String\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = new scope.PointerMap();\n  var tap = {\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel',\n      'keyup'\n    ],\n    pointerdown: function(inEvent) {\n      if (inEvent.isPrimary && !inEvent.tapPrevented) {\n        pointermap.set(inEvent.pointerId, {\n          target: inEvent.target,\n          buttons: inEvent.buttons,\n          x: inEvent.clientX,\n          y: inEvent.clientY\n        });\n      }\n    },\n    pointermove: function(inEvent) {\n      if (inEvent.isPrimary) {\n        var start = pointermap.get(inEvent.pointerId);\n        if (start) {\n          if (inEvent.tapPrevented) {\n            pointermap.delete(inEvent.pointerId);\n          }\n        }\n      }\n    },\n    shouldTap: function(e, downState) {\n      if (!e.tapPrevented) {\n        if (e.pointerType === 'mouse') {\n          // only allow left click to tap for mouse\n          return downState.buttons === 1;\n        } else {\n          return true;\n        }\n      }\n    },\n    pointerup: function(inEvent) {\n      var start = pointermap.get(inEvent.pointerId);\n      if (start && this.shouldTap(inEvent, start)) {\n        var t = scope.findLCA(start.target, inEvent.target);\n        if (t) {\n          var e = dispatcher.makeEvent('tap', {\n            x: inEvent.clientX,\n            y: inEvent.clientY,\n            detail: inEvent.detail,\n            pointerType: inEvent.pointerType\n          });\n          dispatcher.dispatchEvent(e, t);\n        }\n      }\n      pointermap.delete(inEvent.pointerId);\n    },\n    pointercancel: function(inEvent) {\n      pointermap.delete(inEvent.pointerId);\n    },\n    keyup: function(inEvent) {\n      var code = inEvent.keyCode;\n      // 32 == spacebar\n      if (code === 32) {\n        var t = inEvent.target;\n        if (!(t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement)) {\n          dispatcher.dispatchEvent(dispatcher.makeEvent('tap', {\n            x: 0,\n            y: 0,\n            detail: 0,\n            pointerType: 'unavailable'\n          }), t);\n        }\n      }\n    },\n    preventTap: function(inPointerId) {\n      pointermap.delete(inPointerId);\n    }\n  };\n  dispatcher.registerRecognizer('tap', tap);\n})(window.PointerGestures);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Because recognizers are loaded after dispatcher, we have to wait to register\n * scopes until after all the recognizers.\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  function registerScopes() {\n    dispatcher.immediateRegister = true;\n    var rq = dispatcher.registerQueue;\n    rq.forEach(scope.register);\n    rq.length = 0;\n  }\n  if (document.readyState === 'complete') {\n    registerScopes();\n  } else {\n    // register scopes after a steadystate is reached\n    // less MutationObserver churn\n    document.addEventListener('readystatechange', function() {\n      if (document.readyState === 'complete') {\n        registerScopes();\n      }\n    });\n  }\n})(window.PointerGestures);\n","// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(global) {\n  'use strict';\n\n  var filter = Array.prototype.filter.call.bind(Array.prototype.filter);\n\n  function getTreeScope(node) {\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n\n    return typeof node.getElementById === 'function' ? node : null;\n  }\n\n\n  Node.prototype.bind = function(name, observable) {\n    console.error('Unhandled binding to Node: ', this, name, observable);\n  };\n\n  function unbind(node, name) {\n    var bindings = node.bindings;\n    if (!bindings) {\n      node.bindings = {};\n      return;\n    }\n\n    var binding = bindings[name];\n    if (!binding)\n      return;\n\n    binding.close();\n    bindings[name] = undefined;\n  }\n\n  Node.prototype.unbind = function(name) {\n    unbind(this, name);\n  };\n\n  Node.prototype.unbindAll = function() {\n    if (!this.bindings)\n      return;\n    var names = Object.keys(this.bindings);\n    for (var i = 0; i < names.length; i++) {\n      var binding = this.bindings[names[i]];\n      if (binding)\n        binding.close();\n    }\n\n    this.bindings = {};\n  };\n\n  function sanitizeValue(value) {\n    return value == null ? '' : value;\n  }\n\n  function updateText(node, value) {\n    node.data = sanitizeValue(value);\n  }\n\n  function textBinding(node) {\n    return function(value) {\n      return updateText(node, value);\n    };\n  }\n\n  Text.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'textContent')\n      return Node.prototype.bind.call(this, name, value, oneTime);\n\n    if (oneTime)\n      return updateText(this, value);\n\n    unbind(this, 'textContent');\n    updateText(this, value.open(textBinding(this)));\n    return this.bindings.textContent = value;\n  }\n\n  function updateAttribute(el, name, conditional, value) {\n    if (conditional) {\n      if (value)\n        el.setAttribute(name, '');\n      else\n        el.removeAttribute(name);\n      return;\n    }\n\n    el.setAttribute(name, sanitizeValue(value));\n  }\n\n  function attributeBinding(el, name, conditional) {\n    return function(value) {\n      updateAttribute(el, name, conditional, value);\n    };\n  }\n\n  Element.prototype.bind = function(name, value, oneTime) {\n    var conditional = name[name.length - 1] == '?';\n    if (conditional) {\n      this.removeAttribute(name);\n      name = name.slice(0, -1);\n    }\n\n    if (oneTime)\n      return updateAttribute(this, name, conditional, value);\n\n    unbind(this, name);\n    updateAttribute(this, name, conditional,\n        value.open(attributeBinding(this, name, conditional)));\n\n    return this.bindings[name] = value;\n  };\n\n  var checkboxEventType;\n  (function() {\n    // Attempt to feature-detect which event (change or click) is fired first\n    // for checkboxes.\n    var div = document.createElement('div');\n    var checkbox = div.appendChild(document.createElement('input'));\n    checkbox.setAttribute('type', 'checkbox');\n    var first;\n    var count = 0;\n    checkbox.addEventListener('click', function(e) {\n      count++;\n      first = first || 'click';\n    });\n    checkbox.addEventListener('change', function() {\n      count++;\n      first = first || 'change';\n    });\n\n    var event = document.createEvent('MouseEvent');\n    event.initMouseEvent(\"click\", true, true, window, 0, 0, 0, 0, 0, false,\n        false, false, false, 0, null);\n    checkbox.dispatchEvent(event);\n    // WebKit/Blink don't fire the change event if the element is outside the\n    // document, so assume 'change' for that case.\n    checkboxEventType = count == 1 ? 'change' : first;\n  })();\n\n  function getEventForInputType(element) {\n    switch (element.type) {\n      case 'checkbox':\n        return checkboxEventType;\n      case 'radio':\n      case 'select-multiple':\n      case 'select-one':\n        return 'change';\n      case 'range':\n        if (/Trident|MSIE/.test(navigator.userAgent))\n          return 'change';\n      default:\n        return 'input';\n    }\n  }\n\n  function updateInput(input, property, value, santizeFn) {\n    input[property] = (santizeFn || sanitizeValue)(value);\n  }\n\n  function inputBinding(input, property, santizeFn) {\n    return function(value) {\n      return updateInput(input, property, value, santizeFn);\n    }\n  }\n\n  function noop() {}\n\n  function bindInputEvent(input, property, observable, postEventFn) {\n    var eventType = getEventForInputType(input);\n\n    function eventHandler() {\n      observable.setValue(input[property]);\n      observable.discardChanges();\n      (postEventFn || noop)(input);\n      Platform.performMicrotaskCheckpoint();\n    }\n    input.addEventListener(eventType, eventHandler);\n\n    var capturedClose = observable.close;\n    observable.close = function() {\n      if (!capturedClose)\n        return;\n      input.removeEventListener(eventType, eventHandler);\n\n      observable.close = capturedClose;\n      observable.close();\n      capturedClose = undefined;\n    }\n  }\n\n  function booleanSanitize(value) {\n    return Boolean(value);\n  }\n\n  // |element| is assumed to be an HTMLInputElement with |type| == 'radio'.\n  // Returns an array containing all radio buttons other than |element| that\n  // have the same |name|, either in the form that |element| belongs to or,\n  // if no form, in the document tree to which |element| belongs.\n  //\n  // This implementation is based upon the HTML spec definition of a\n  // \"radio button group\":\n  //   http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#radio-button-group\n  //\n  function getAssociatedRadioButtons(element) {\n    if (element.form) {\n      return filter(element.form.elements, function(el) {\n        return el != element &&\n            el.tagName == 'INPUT' &&\n            el.type == 'radio' &&\n            el.name == element.name;\n      });\n    } else {\n      var treeScope = getTreeScope(element);\n      if (!treeScope)\n        return [];\n      var radios = treeScope.querySelectorAll(\n          'input[type=\"radio\"][name=\"' + element.name + '\"]');\n      return filter(radios, function(el) {\n        return el != element && !el.form;\n      });\n    }\n  }\n\n  function checkedPostEvent(input) {\n    // Only the radio button that is getting checked gets an event. We\n    // therefore find all the associated radio buttons and update their\n    // check binding manually.\n    if (input.tagName === 'INPUT' &&\n        input.type === 'radio') {\n      getAssociatedRadioButtons(input).forEach(function(radio) {\n        var checkedBinding = radio.bindings.checked;\n        if (checkedBinding) {\n          // Set the value directly to avoid an infinite call stack.\n          checkedBinding.setValue(false);\n        }\n      });\n    }\n  }\n\n  HTMLInputElement.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'value' && name !== 'checked')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n\n    this.removeAttribute(name);\n    var sanitizeFn = name == 'checked' ? booleanSanitize : sanitizeValue;\n    var postEventFn = name == 'checked' ? checkedPostEvent : noop;\n\n    if (oneTime)\n      return updateInput(this, name, value, sanitizeFn);\n\n    unbind(this, name);\n    bindInputEvent(this, name, value, postEventFn);\n    updateInput(this, name,\n                value.open(inputBinding(this, name, sanitizeFn)),\n                sanitizeFn);\n\n    return this.bindings[name] = value;\n  }\n\n  HTMLTextAreaElement.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'value')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n    this.removeAttribute('value');\n\n    if (oneTime)\n      return updateInput(this, 'value', value);\n\n    unbind(this, 'value');\n    bindInputEvent(this, 'value', value);\n    updateInput(this, 'value',\n                value.open(inputBinding(this, 'value', sanitizeValue)));\n\n    return this.bindings.value = value;\n  }\n\n  function updateOption(option, value) {\n    var parentNode = option.parentNode;;\n    var select;\n    var selectBinding;\n    var oldValue;\n    if (parentNode instanceof HTMLSelectElement &&\n        parentNode.bindings &&\n        parentNode.bindings.value) {\n      select = parentNode;\n      selectBinding = select.bindings.value;\n      oldValue = select.value;\n    }\n\n    option.value = sanitizeValue(value);\n\n    if (select && select.value != oldValue) {\n      selectBinding.setValue(select.value);\n      selectBinding.discardChanges();\n      Platform.performMicrotaskCheckpoint();\n    }\n  }\n\n  function optionBinding(option) {\n    return function(value) {\n      updateOption(option, value);\n    }\n  }\n\n  HTMLOptionElement.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'value')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n    this.removeAttribute('value');\n\n    if (oneTime)\n      return updateOption(this, value);\n\n    unbind(this, 'value');\n    bindInputEvent(this, 'value', value);\n    updateOption(this, value.open(optionBinding(this)));\n    return this.bindings.value = value;\n  }\n\n  HTMLSelectElement.prototype.bind = function(name, value, oneTime) {\n    if (name === 'selectedindex')\n      name = 'selectedIndex';\n\n    if (name !== 'selectedIndex' && name !== 'value')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n    this.removeAttribute(name);\n\n    if (oneTime)\n      return updateInput(this, name, value);\n\n    unbind(this, name);\n    bindInputEvent(this, name, value);\n    updateInput(this, name,\n                value.open(inputBinding(this, name)));\n    return this.bindings[name] = value;\n  }\n})(this);\n","// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(global) {\n  'use strict';\n\n  function assert(v) {\n    if (!v)\n      throw new Error('Assertion failed');\n  }\n\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n\n  function getFragmentRoot(node) {\n    var p;\n    while (p = node.parentNode) {\n      node = p;\n    }\n\n    return node;\n  }\n\n  function searchRefId(node, id) {\n    if (!id)\n      return;\n\n    var ref;\n    var selector = '#' + id;\n    while (!ref) {\n      node = getFragmentRoot(node);\n\n      if (node.protoContent_)\n        ref = node.protoContent_.querySelector(selector);\n      else if (node.getElementById)\n        ref = node.getElementById(id);\n\n      if (ref || !node.templateCreator_)\n        break\n\n      node = node.templateCreator_;\n    }\n\n    return ref;\n  }\n\n  function getInstanceRoot(node) {\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n    return node.templateCreator_ ? node : null;\n  }\n\n  var Map;\n  if (global.Map && typeof global.Map.prototype.forEach === 'function') {\n    Map = global.Map;\n  } else {\n    Map = function() {\n      this.keys = [];\n      this.values = [];\n    };\n\n    Map.prototype = {\n      set: function(key, value) {\n        var index = this.keys.indexOf(key);\n        if (index < 0) {\n          this.keys.push(key);\n          this.values.push(value);\n        } else {\n          this.values[index] = value;\n        }\n      },\n\n      get: function(key) {\n        var index = this.keys.indexOf(key);\n        if (index < 0)\n          return;\n\n        return this.values[index];\n      },\n\n      delete: function(key, value) {\n        var index = this.keys.indexOf(key);\n        if (index < 0)\n          return false;\n\n        this.keys.splice(index, 1);\n        this.values.splice(index, 1);\n        return true;\n      },\n\n      forEach: function(f, opt_this) {\n        for (var i = 0; i < this.keys.length; i++)\n          f.call(opt_this || this, this.values[i], this.keys[i], this);\n      }\n    };\n  }\n\n  // JScript does not have __proto__. We wrap all object literals with\n  // createObject which uses Object.create, Object.defineProperty and\n  // Object.getOwnPropertyDescriptor to create a new object that does the exact\n  // same thing. The main downside to this solution is that we have to extract\n  // all those property descriptors for IE.\n  var createObject = ('__proto__' in {}) ?\n      function(obj) { return obj; } :\n      function(obj) {\n        var proto = obj.__proto__;\n        if (!proto)\n          return obj;\n        var newObject = Object.create(proto);\n        Object.getOwnPropertyNames(obj).forEach(function(name) {\n          Object.defineProperty(newObject, name,\n                               Object.getOwnPropertyDescriptor(obj, name));\n        });\n        return newObject;\n      };\n\n  // IE does not support have Document.prototype.contains.\n  if (typeof document.contains != 'function') {\n    Document.prototype.contains = function(node) {\n      if (node === this || node.parentNode === this)\n        return true;\n      return this.documentElement.contains(node);\n    }\n  }\n\n  var BIND = 'bind';\n  var REPEAT = 'repeat';\n  var IF = 'if';\n\n  var templateAttributeDirectives = {\n    'template': true,\n    'repeat': true,\n    'bind': true,\n    'ref': true\n  };\n\n  var semanticTemplateElements = {\n    'THEAD': true,\n    'TBODY': true,\n    'TFOOT': true,\n    'TH': true,\n    'TR': true,\n    'TD': true,\n    'COLGROUP': true,\n    'COL': true,\n    'CAPTION': true,\n    'OPTION': true,\n    'OPTGROUP': true\n  };\n\n  var hasTemplateElement = typeof HTMLTemplateElement !== 'undefined';\n  if (hasTemplateElement) {\n    // TODO(rafaelw): Remove when fix for\n    // https://codereview.chromium.org/164803002/\n    // makes it to Chrome release.\n    (function() {\n      var t = document.createElement('template');\n      var d = t.content.ownerDocument;\n      var html = d.appendChild(d.createElement('html'));\n      var head = html.appendChild(d.createElement('head'));\n      var base = d.createElement('base');\n      base.href = document.baseURI;\n      head.appendChild(base);\n    })();\n  }\n\n  var allTemplatesSelectors = 'template, ' +\n      Object.keys(semanticTemplateElements).map(function(tagName) {\n        return tagName.toLowerCase() + '[template]';\n      }).join(', ');\n\n  function isSVGTemplate(el) {\n    return el.tagName == 'template' &&\n           el.namespaceURI == 'http://www.w3.org/2000/svg';\n  }\n\n  function isHTMLTemplate(el) {\n    return el.tagName == 'TEMPLATE' &&\n           el.namespaceURI == 'http://www.w3.org/1999/xhtml';\n  }\n\n  function isAttributeTemplate(el) {\n    return Boolean(semanticTemplateElements[el.tagName] &&\n                   el.hasAttribute('template'));\n  }\n\n  function isTemplate(el) {\n    if (el.isTemplate_ === undefined)\n      el.isTemplate_ = el.tagName == 'TEMPLATE' || isAttributeTemplate(el);\n\n    return el.isTemplate_;\n  }\n\n  // FIXME: Observe templates being added/removed from documents\n  // FIXME: Expose imperative API to decorate and observe templates in\n  // \"disconnected tress\" (e.g. ShadowRoot)\n  document.addEventListener('DOMContentLoaded', function(e) {\n    bootstrapTemplatesRecursivelyFrom(document);\n    // FIXME: Is this needed? Seems like it shouldn't be.\n    Platform.performMicrotaskCheckpoint();\n  }, false);\n\n  function forAllTemplatesFrom(node, fn) {\n    var subTemplates = node.querySelectorAll(allTemplatesSelectors);\n\n    if (isTemplate(node))\n      fn(node)\n    forEach(subTemplates, fn);\n  }\n\n  function bootstrapTemplatesRecursivelyFrom(node) {\n    function bootstrap(template) {\n      if (!HTMLTemplateElement.decorate(template))\n        bootstrapTemplatesRecursivelyFrom(template.content);\n    }\n\n    forAllTemplatesFrom(node, bootstrap);\n  }\n\n  if (!hasTemplateElement) {\n    /**\n     * This represents a <template> element.\n     * @constructor\n     * @extends {HTMLElement}\n     */\n    global.HTMLTemplateElement = function() {\n      throw TypeError('Illegal constructor');\n    };\n  }\n\n  var hasProto = '__proto__' in {};\n\n  function mixin(to, from) {\n    Object.getOwnPropertyNames(from).forEach(function(name) {\n      Object.defineProperty(to, name,\n                            Object.getOwnPropertyDescriptor(from, name));\n    });\n  }\n\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner\n  function getOrCreateTemplateContentsOwner(template) {\n    var doc = template.ownerDocument\n    if (!doc.defaultView)\n      return doc;\n    var d = doc.templateContentsOwner_;\n    if (!d) {\n      // TODO(arv): This should either be a Document or HTMLDocument depending\n      // on doc.\n      d = doc.implementation.createHTMLDocument('');\n      while (d.lastChild) {\n        d.removeChild(d.lastChild);\n      }\n      doc.templateContentsOwner_ = d;\n    }\n    return d;\n  }\n\n  function getTemplateStagingDocument(template) {\n    if (!template.stagingDocument_) {\n      var owner = template.ownerDocument;\n      if (!owner.stagingDocument_) {\n        owner.stagingDocument_ = owner.implementation.createHTMLDocument('');\n\n        // TODO(rafaelw): Remove when fix for\n        // https://codereview.chromium.org/164803002/\n        // makes it to Chrome release.\n        var base = owner.stagingDocument_.createElement('base');\n        base.href = document.baseURI;\n        owner.stagingDocument_.head.appendChild(base);\n\n        owner.stagingDocument_.stagingDocument_ = owner.stagingDocument_;\n      }\n\n      template.stagingDocument_ = owner.stagingDocument_;\n    }\n\n    return template.stagingDocument_;\n  }\n\n  // For non-template browsers, the parser will disallow <template> in certain\n  // locations, so we allow \"attribute templates\" which combine the template\n  // element with the top-level container node of the content, e.g.\n  //\n  //   <tr template repeat=\"{{ foo }}\"\" class=\"bar\"><td>Bar</td></tr>\n  //\n  // becomes\n  //\n  //   <template repeat=\"{{ foo }}\">\n  //   + #document-fragment\n  //     + <tr class=\"bar\">\n  //       + <td>Bar</td>\n  //\n  function extractTemplateFromAttributeTemplate(el) {\n    var template = el.ownerDocument.createElement('template');\n    el.parentNode.insertBefore(template, el);\n\n    var attribs = el.attributes;\n    var count = attribs.length;\n    while (count-- > 0) {\n      var attrib = attribs[count];\n      if (templateAttributeDirectives[attrib.name]) {\n        if (attrib.name !== 'template')\n          template.setAttribute(attrib.name, attrib.value);\n        el.removeAttribute(attrib.name);\n      }\n    }\n\n    return template;\n  }\n\n  function extractTemplateFromSVGTemplate(el) {\n    var template = el.ownerDocument.createElement('template');\n    el.parentNode.insertBefore(template, el);\n\n    var attribs = el.attributes;\n    var count = attribs.length;\n    while (count-- > 0) {\n      var attrib = attribs[count];\n      template.setAttribute(attrib.name, attrib.value);\n      el.removeAttribute(attrib.name);\n    }\n\n    el.parentNode.removeChild(el);\n    return template;\n  }\n\n  function liftNonNativeTemplateChildrenIntoContent(template, el, useRoot) {\n    var content = template.content;\n    if (useRoot) {\n      content.appendChild(el);\n      return;\n    }\n\n    var child;\n    while (child = el.firstChild) {\n      content.appendChild(child);\n    }\n  }\n\n  var templateObserver;\n  if (typeof MutationObserver == 'function') {\n    templateObserver = new MutationObserver(function(records) {\n      for (var i = 0; i < records.length; i++) {\n        records[i].target.refChanged_();\n      }\n    });\n  }\n\n  /**\n   * Ensures proper API and content model for template elements.\n   * @param {HTMLTemplateElement} opt_instanceRef The template element which\n   *     |el| template element will return as the value of its ref(), and whose\n   *     content will be used as source when createInstance() is invoked.\n   */\n  HTMLTemplateElement.decorate = function(el, opt_instanceRef) {\n    if (el.templateIsDecorated_)\n      return false;\n\n    var templateElement = el;\n    templateElement.templateIsDecorated_ = true;\n\n    var isNativeHTMLTemplate = isHTMLTemplate(templateElement) &&\n                               hasTemplateElement;\n    var bootstrapContents = isNativeHTMLTemplate;\n    var liftContents = !isNativeHTMLTemplate;\n    var liftRoot = false;\n\n    if (!isNativeHTMLTemplate) {\n      if (isAttributeTemplate(templateElement)) {\n        assert(!opt_instanceRef);\n        templateElement = extractTemplateFromAttributeTemplate(el);\n        templateElement.templateIsDecorated_ = true;\n        isNativeHTMLTemplate = hasTemplateElement;\n        liftRoot = true;\n      } else if (isSVGTemplate(templateElement)) {\n        templateElement = extractTemplateFromSVGTemplate(el);\n        templateElement.templateIsDecorated_ = true;\n        isNativeHTMLTemplate = hasTemplateElement;\n      }\n    }\n\n    if (!isNativeHTMLTemplate) {\n      fixTemplateElementPrototype(templateElement);\n      var doc = getOrCreateTemplateContentsOwner(templateElement);\n      templateElement.content_ = doc.createDocumentFragment();\n    }\n\n    if (opt_instanceRef) {\n      // template is contained within an instance, its direct content must be\n      // empty\n      templateElement.instanceRef_ = opt_instanceRef;\n    } else if (liftContents) {\n      liftNonNativeTemplateChildrenIntoContent(templateElement,\n                                               el,\n                                               liftRoot);\n    } else if (bootstrapContents) {\n      bootstrapTemplatesRecursivelyFrom(templateElement.content);\n    }\n\n    return true;\n  };\n\n  // TODO(rafaelw): This used to decorate recursively all templates from a given\n  // node. This happens by default on 'DOMContentLoaded', but may be needed\n  // in subtrees not descendent from document (e.g. ShadowRoot).\n  // Review whether this is the right public API.\n  HTMLTemplateElement.bootstrap = bootstrapTemplatesRecursivelyFrom;\n\n  var htmlElement = global.HTMLUnknownElement || HTMLElement;\n\n  var contentDescriptor = {\n    get: function() {\n      return this.content_;\n    },\n    enumerable: true,\n    configurable: true\n  };\n\n  if (!hasTemplateElement) {\n    // Gecko is more picky with the prototype than WebKit. Make sure to use the\n    // same prototype as created in the constructor.\n    HTMLTemplateElement.prototype = Object.create(htmlElement.prototype);\n\n    Object.defineProperty(HTMLTemplateElement.prototype, 'content',\n                          contentDescriptor);\n  }\n\n  function fixTemplateElementPrototype(el) {\n    if (hasProto)\n      el.__proto__ = HTMLTemplateElement.prototype;\n    else\n      mixin(el, HTMLTemplateElement.prototype);\n  }\n\n  function ensureSetModelScheduled(template) {\n    if (!template.setModelFn_) {\n      template.setModelFn_ = function() {\n        template.setModelFnScheduled_ = false;\n        var map = getBindings(template,\n            template.delegate_ && template.delegate_.prepareBinding);\n        processBindings(template, map, template.model_);\n      };\n    }\n\n    if (!template.setModelFnScheduled_) {\n      template.setModelFnScheduled_ = true;\n      Observer.runEOM_(template.setModelFn_);\n    }\n  }\n\n  mixin(HTMLTemplateElement.prototype, {\n    bind: function(name, value, oneTime) {\n      if (name != 'ref')\n        return Element.prototype.bind.call(this, name, value, oneTime);\n\n      var self = this;\n      var ref = oneTime ? value : value.open(function(ref) {\n        self.setAttribute('ref', ref);\n        self.refChanged_();\n      });\n\n      this.setAttribute('ref', ref);\n      this.refChanged_();\n      if (oneTime)\n        return;\n\n      this.unbind('ref');\n      return this.bindings.ref = value;\n    },\n\n    processBindingDirectives_: function(directives) {\n      if (this.iterator_)\n        this.iterator_.closeDeps();\n\n      if (!directives.if && !directives.bind && !directives.repeat) {\n        if (this.iterator_) {\n          this.iterator_.close();\n          this.iterator_ = undefined;\n          this.bindings.iterator = undefined;\n        }\n\n        return;\n      }\n\n      if (!this.iterator_) {\n        this.iterator_ = new TemplateIterator(this);\n        this.bindings = this.bindings || {};\n        this.bindings.iterator = this.iterator_;\n      }\n\n      this.iterator_.updateDependencies(directives, this.model_);\n\n      if (templateObserver) {\n        templateObserver.observe(this, { attributes: true,\n                                         attributeFilter: ['ref'] });\n      }\n\n      return this.iterator_;\n    },\n\n    createInstance: function(model, bindingDelegate, delegate_,\n                             instanceBindings_) {\n      if (bindingDelegate)\n        delegate_ = this.newDelegate_(bindingDelegate);\n\n      if (!this.refContent_)\n        this.refContent_ = this.ref_.content;\n      var content = this.refContent_;\n      var map = this.bindingMap_;\n      if (!map || map.content !== content) {\n        // TODO(rafaelw): Setup a MutationObserver on content to detect\n        // when the instanceMap is invalid.\n        map = createInstanceBindingMap(content,\n            delegate_ && delegate_.prepareBinding) || [];\n        map.content = content;\n        this.bindingMap_ = map;\n      }\n\n      var stagingDocument = getTemplateStagingDocument(this);\n      var instance = stagingDocument.createDocumentFragment();\n      instance.templateCreator_ = this;\n      instance.protoContent_ = content;\n\n      var instanceRecord = {\n        firstNode: null,\n        lastNode: null,\n        model: model\n      };\n\n      var i = 0;\n      for (var child = content.firstChild; child; child = child.nextSibling) {\n        var clone = cloneAndBindInstance(child, instance, stagingDocument,\n                                         map.children[i++],\n                                         model,\n                                         delegate_,\n                                         instanceBindings_);\n        clone.templateInstance_ = instanceRecord;\n      }\n\n      instanceRecord.firstNode = instance.firstChild;\n      instanceRecord.lastNode = instance.lastChild;\n      instance.templateCreator_ = undefined;\n      instance.protoContent_ = undefined;\n      return instance;\n    },\n\n    get model() {\n      return this.model_;\n    },\n\n    set model(model) {\n      this.model_ = model;\n      ensureSetModelScheduled(this);\n    },\n\n    get bindingDelegate() {\n      return this.delegate_ && this.delegate_.raw;\n    },\n\n    refChanged_: function() {\n      if (!this.iterator_ || this.refContent_ === this.ref_.content)\n        return;\n\n      this.refContent_ = undefined;\n      this.iterator_.valueChanged();\n      this.iterator_.updateIteratedValue();\n    },\n\n    clear: function() {\n      this.model_ = undefined;\n      this.delegate_ = undefined;\n      this.bindings_ = undefined;\n      this.refContent_ = undefined;\n      if (!this.iterator_)\n        return;\n      this.iterator_.valueChanged();\n      this.iterator_.close()\n      this.iterator_ = undefined;\n    },\n\n    setDelegate_: function(delegate) {\n      this.delegate_ = delegate;\n      this.bindingMap_ = undefined;\n      if (this.iterator_) {\n        this.iterator_.instancePositionChangedFn_ = undefined;\n        this.iterator_.instanceModelFn_ = undefined;\n      }\n    },\n\n    newDelegate_: function(bindingDelegate) {\n      if (!bindingDelegate)\n        return {};\n\n      function delegateFn(name) {\n        var fn = bindingDelegate && bindingDelegate[name];\n        if (typeof fn != 'function')\n          return;\n\n        return function() {\n          return fn.apply(bindingDelegate, arguments);\n        };\n      }\n\n      return {\n        raw: bindingDelegate,\n        prepareBinding: delegateFn('prepareBinding'),\n        prepareInstanceModel: delegateFn('prepareInstanceModel'),\n        prepareInstancePositionChanged:\n            delegateFn('prepareInstancePositionChanged')\n      };\n    },\n\n    // TODO(rafaelw): Assigning .bindingDelegate always succeeds. It may\n    // make sense to issue a warning or even throw if the template is already\n    // \"activated\", since this would be a strange thing to do.\n    set bindingDelegate(bindingDelegate) {\n      if (this.delegate_) {\n        throw Error('Template must be cleared before a new bindingDelegate ' +\n                    'can be assigned');\n      }\n\n      this.setDelegate_(this.newDelegate_(bindingDelegate));\n    },\n\n    get ref_() {\n      var ref = searchRefId(this, this.getAttribute('ref'));\n      if (!ref)\n        ref = this.instanceRef_;\n\n      if (!ref)\n        return this;\n\n      var nextRef = ref.ref_;\n      return nextRef ? nextRef : ref;\n    }\n  });\n\n  // Returns\n  //   a) undefined if there are no mustaches.\n  //   b) [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+] if there is at least one mustache.\n  function parseMustaches(s, name, node, prepareBindingFn) {\n    if (!s || !s.length)\n      return;\n\n    var tokens;\n    var length = s.length;\n    var startIndex = 0, lastIndex = 0, endIndex = 0;\n    var onlyOneTime = true;\n    while (lastIndex < length) {\n      var startIndex = s.indexOf('{{', lastIndex);\n      var oneTimeStart = s.indexOf('[[', lastIndex);\n      var oneTime = false;\n      var terminator = '}}';\n\n      if (oneTimeStart >= 0 &&\n          (startIndex < 0 || oneTimeStart < startIndex)) {\n        startIndex = oneTimeStart;\n        oneTime = true;\n        terminator = ']]';\n      }\n\n      endIndex = startIndex < 0 ? -1 : s.indexOf(terminator, startIndex + 2);\n\n      if (endIndex < 0) {\n        if (!tokens)\n          return;\n\n        tokens.push(s.slice(lastIndex)); // TEXT\n        break;\n      }\n\n      tokens = tokens || [];\n      tokens.push(s.slice(lastIndex, startIndex)); // TEXT\n      var pathString = s.slice(startIndex + 2, endIndex).trim();\n      tokens.push(oneTime); // ONE_TIME?\n      onlyOneTime = onlyOneTime && oneTime;\n      tokens.push(Path.get(pathString)); // PATH\n      var delegateFn = prepareBindingFn &&\n                       prepareBindingFn(pathString, name, node);\n      tokens.push(delegateFn); // DELEGATE_FN\n      lastIndex = endIndex + 2;\n    }\n\n    if (lastIndex === length)\n      tokens.push(''); // TEXT\n\n    tokens.hasOnePath = tokens.length === 5;\n    tokens.isSimplePath = tokens.hasOnePath &&\n                          tokens[0] == '' &&\n                          tokens[4] == '';\n    tokens.onlyOneTime = onlyOneTime;\n\n    tokens.combinator = function(values) {\n      var newValue = tokens[0];\n\n      for (var i = 1; i < tokens.length; i += 4) {\n        var value = tokens.hasOnePath ? values : values[(i - 1) / 4];\n        if (value !== undefined)\n          newValue += value;\n        newValue += tokens[i + 3];\n      }\n\n      return newValue;\n    }\n\n    return tokens;\n  };\n\n  function processOneTimeBinding(name, tokens, node, model) {\n    if (tokens.hasOnePath) {\n      var delegateFn = tokens[3];\n      var value = delegateFn ? delegateFn(model, node, true) :\n                               tokens[2].getValueFrom(model);\n      return tokens.isSimplePath ? value : tokens.combinator(value);\n    }\n\n    var values = [];\n    for (var i = 1; i < tokens.length; i += 4) {\n      var delegateFn = tokens[i + 2];\n      values[(i - 1) / 4] = delegateFn ? delegateFn(model, node) :\n          tokens[i + 1].getValueFrom(model);\n    }\n\n    return tokens.combinator(values);\n  }\n\n  function processSinglePathBinding(name, tokens, node, model) {\n    var delegateFn = tokens[3];\n    var observer = delegateFn ? delegateFn(model, node, false) :\n        new PathObserver(model, tokens[2]);\n\n    return tokens.isSimplePath ? observer :\n        new ObserverTransform(observer, tokens.combinator);\n  }\n\n  function processBinding(name, tokens, node, model) {\n    if (tokens.onlyOneTime)\n      return processOneTimeBinding(name, tokens, node, model);\n\n    if (tokens.hasOnePath)\n      return processSinglePathBinding(name, tokens, node, model);\n\n    var observer = new CompoundObserver();\n\n    for (var i = 1; i < tokens.length; i += 4) {\n      var oneTime = tokens[i];\n      var delegateFn = tokens[i + 2];\n\n      if (delegateFn) {\n        var value = delegateFn(model, node, oneTime);\n        if (oneTime)\n          observer.addPath(value)\n        else\n          observer.addObserver(value);\n        continue;\n      }\n\n      var path = tokens[i + 1];\n      if (oneTime)\n        observer.addPath(path.getValueFrom(model))\n      else\n        observer.addPath(model, path);\n    }\n\n    return new ObserverTransform(observer, tokens.combinator);\n  }\n\n  function processBindings(node, bindings, model, instanceBindings) {\n    for (var i = 0; i < bindings.length; i += 2) {\n      var name = bindings[i]\n      var tokens = bindings[i + 1];\n      var value = processBinding(name, tokens, node, model);\n      var binding = node.bind(name, value, tokens.onlyOneTime);\n      if (binding && instanceBindings)\n        instanceBindings.push(binding);\n    }\n\n    if (!bindings.isTemplate)\n      return;\n\n    node.model_ = model;\n    var iter = node.processBindingDirectives_(bindings);\n    if (instanceBindings && iter)\n      instanceBindings.push(iter);\n  }\n\n  function parseWithDefault(el, name, prepareBindingFn) {\n    var v = el.getAttribute(name);\n    return parseMustaches(v == '' ? '{{}}' : v, name, el, prepareBindingFn);\n  }\n\n  function parseAttributeBindings(element, prepareBindingFn) {\n    assert(element);\n\n    var bindings = [];\n    var ifFound = false;\n    var bindFound = false;\n\n    for (var i = 0; i < element.attributes.length; i++) {\n      var attr = element.attributes[i];\n      var name = attr.name;\n      var value = attr.value;\n\n      // Allow bindings expressed in attributes to be prefixed with underbars.\n      // We do this to allow correct semantics for browsers that don't implement\n      // <template> where certain attributes might trigger side-effects -- and\n      // for IE which sanitizes certain attributes, disallowing mustache\n      // replacements in their text.\n      while (name[0] === '_') {\n        name = name.substring(1);\n      }\n\n      if (isTemplate(element) &&\n          (name === IF || name === BIND || name === REPEAT)) {\n        continue;\n      }\n\n      var tokens = parseMustaches(value, name, element,\n                                  prepareBindingFn);\n      if (!tokens)\n        continue;\n\n      bindings.push(name, tokens);\n    }\n\n    if (isTemplate(element)) {\n      bindings.isTemplate = true;\n      bindings.if = parseWithDefault(element, IF, prepareBindingFn);\n      bindings.bind = parseWithDefault(element, BIND, prepareBindingFn);\n      bindings.repeat = parseWithDefault(element, REPEAT, prepareBindingFn);\n\n      if (bindings.if && !bindings.bind && !bindings.repeat)\n        bindings.bind = parseMustaches('{{}}', BIND, element, prepareBindingFn);\n    }\n\n    return bindings;\n  }\n\n  function getBindings(node, prepareBindingFn) {\n    if (node.nodeType === Node.ELEMENT_NODE)\n      return parseAttributeBindings(node, prepareBindingFn);\n\n    if (node.nodeType === Node.TEXT_NODE) {\n      var tokens = parseMustaches(node.data, 'textContent', node,\n                                  prepareBindingFn);\n      if (tokens)\n        return ['textContent', tokens];\n    }\n\n    return [];\n  }\n\n  function cloneAndBindInstance(node, parent, stagingDocument, bindings, model,\n                                delegate,\n                                instanceBindings,\n                                instanceRecord) {\n    var clone = parent.appendChild(stagingDocument.importNode(node, false));\n\n    var i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      cloneAndBindInstance(child, clone, stagingDocument,\n                            bindings.children[i++],\n                            model,\n                            delegate,\n                            instanceBindings);\n    }\n\n    if (bindings.isTemplate) {\n      HTMLTemplateElement.decorate(clone, node);\n      if (delegate)\n        clone.setDelegate_(delegate);\n    }\n\n    processBindings(clone, bindings, model, instanceBindings);\n    return clone;\n  }\n\n  function createInstanceBindingMap(node, prepareBindingFn) {\n    var map = getBindings(node, prepareBindingFn);\n    map.children = {};\n    var index = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      map.children[index++] = createInstanceBindingMap(child, prepareBindingFn);\n    }\n\n    return map;\n  }\n\n  Object.defineProperty(Node.prototype, 'templateInstance', {\n    get: function() {\n      var instance = this.templateInstance_;\n      return instance ? instance :\n          (this.parentNode ? this.parentNode.templateInstance : undefined);\n    }\n  });\n\n  function TemplateIterator(templateElement) {\n    this.closed = false;\n    this.templateElement_ = templateElement;\n\n    // Flattened array of tuples:\n    //   <instanceTerminatorNode, [bindingsSetupByInstance]>\n    this.terminators = [];\n\n    this.deps = undefined;\n    this.iteratedValue = [];\n    this.presentValue = undefined;\n    this.arrayObserver = undefined;\n  }\n\n  TemplateIterator.prototype = {\n    closeDeps: function() {\n      var deps = this.deps;\n      if (deps) {\n        if (deps.ifOneTime === false)\n          deps.ifValue.close();\n        if (deps.oneTime === false)\n          deps.value.close();\n      }\n    },\n\n    updateDependencies: function(directives, model) {\n      this.closeDeps();\n\n      var deps = this.deps = {};\n      var template = this.templateElement_;\n\n      if (directives.if) {\n        deps.hasIf = true;\n        deps.ifOneTime = directives.if.onlyOneTime;\n        deps.ifValue = processBinding(IF, directives.if, template, model);\n\n        // oneTime if & predicate is false. nothing else to do.\n        if (deps.ifOneTime && !deps.ifValue) {\n          this.updateIteratedValue();\n          return;\n        }\n\n        if (!deps.ifOneTime)\n          deps.ifValue.open(this.updateIteratedValue, this);\n      }\n\n      if (directives.repeat) {\n        deps.repeat = true;\n        deps.oneTime = directives.repeat.onlyOneTime;\n        deps.value = processBinding(REPEAT, directives.repeat, template, model);\n      } else {\n        deps.repeat = false;\n        deps.oneTime = directives.bind.onlyOneTime;\n        deps.value = processBinding(BIND, directives.bind, template, model);\n      }\n\n      if (!deps.oneTime)\n        deps.value.open(this.updateIteratedValue, this);\n\n      this.updateIteratedValue();\n    },\n\n    updateIteratedValue: function() {\n      if (this.deps.hasIf) {\n        var ifValue = this.deps.ifValue;\n        if (!this.deps.ifOneTime)\n          ifValue = ifValue.discardChanges();\n        if (!ifValue) {\n          this.valueChanged();\n          return;\n        }\n      }\n\n      var value = this.deps.value;\n      if (!this.deps.oneTime)\n        value = value.discardChanges();\n      if (!this.deps.repeat)\n        value = [value];\n      var observe = this.deps.repeat &&\n                    !this.deps.oneTime &&\n                    Array.isArray(value);\n      this.valueChanged(value, observe);\n    },\n\n    valueChanged: function(value, observeValue) {\n      if (!Array.isArray(value))\n        value = [];\n\n      if (value === this.iteratedValue)\n        return;\n\n      this.unobserve();\n      this.presentValue = value;\n      if (observeValue) {\n        this.arrayObserver = new ArrayObserver(this.presentValue);\n        this.arrayObserver.open(this.handleSplices, this);\n      }\n\n      this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,\n                                                        this.iteratedValue));\n    },\n\n    getTerminatorAt: function(index) {\n      if (index == -1)\n        return this.templateElement_;\n      var terminator = this.terminators[index*2];\n      if (terminator.nodeType !== Node.ELEMENT_NODE ||\n          this.templateElement_ === terminator) {\n        return terminator;\n      }\n\n      var subIterator = terminator.iterator_;\n      if (!subIterator)\n        return terminator;\n\n      return subIterator.getTerminatorAt(subIterator.terminators.length/2 - 1);\n    },\n\n    // TODO(rafaelw): If we inserting sequences of instances we can probably\n    // avoid lots of calls to getTerminatorAt(), or cache its result.\n    insertInstanceAt: function(index, fragment, instanceNodes,\n                               instanceBindings) {\n      var previousTerminator = this.getTerminatorAt(index - 1);\n      var terminator = previousTerminator;\n      if (fragment)\n        terminator = fragment.lastChild || terminator;\n      else if (instanceNodes)\n        terminator = instanceNodes[instanceNodes.length - 1] || terminator;\n\n      this.terminators.splice(index*2, 0, terminator, instanceBindings);\n      var parent = this.templateElement_.parentNode;\n      var insertBeforeNode = previousTerminator.nextSibling;\n\n      if (fragment) {\n        parent.insertBefore(fragment, insertBeforeNode);\n      } else if (instanceNodes) {\n        for (var i = 0; i < instanceNodes.length; i++)\n          parent.insertBefore(instanceNodes[i], insertBeforeNode);\n      }\n    },\n\n    extractInstanceAt: function(index) {\n      var instanceNodes = [];\n      var previousTerminator = this.getTerminatorAt(index - 1);\n      var terminator = this.getTerminatorAt(index);\n      instanceNodes.instanceBindings = this.terminators[index*2 + 1];\n      this.terminators.splice(index*2, 2);\n\n      var parent = this.templateElement_.parentNode;\n      while (terminator !== previousTerminator) {\n        var node = previousTerminator.nextSibling;\n        if (node == terminator)\n          terminator = previousTerminator;\n\n        parent.removeChild(node);\n        instanceNodes.push(node);\n      }\n\n      return instanceNodes;\n    },\n\n    getDelegateFn: function(fn) {\n      fn = fn && fn(this.templateElement_);\n      return typeof fn === 'function' ? fn : null;\n    },\n\n    handleSplices: function(splices) {\n      if (this.closed || !splices.length)\n        return;\n\n      var template = this.templateElement_;\n\n      if (!template.parentNode) {\n        this.close();\n        return;\n      }\n\n      ArrayObserver.applySplices(this.iteratedValue, this.presentValue,\n                                 splices);\n\n      var delegate = template.delegate_;\n      if (this.instanceModelFn_ === undefined) {\n        this.instanceModelFn_ =\n            this.getDelegateFn(delegate && delegate.prepareInstanceModel);\n      }\n\n      if (this.instancePositionChangedFn_ === undefined) {\n        this.instancePositionChangedFn_ =\n            this.getDelegateFn(delegate &&\n                               delegate.prepareInstancePositionChanged);\n      }\n\n      var instanceCache = new Map;\n      var removeDelta = 0;\n      splices.forEach(function(splice) {\n        splice.removed.forEach(function(model) {\n          var instanceNodes =\n              this.extractInstanceAt(splice.index + removeDelta);\n          instanceCache.set(model, instanceNodes);\n        }, this);\n\n        removeDelta -= splice.addedCount;\n      }, this);\n\n      splices.forEach(function(splice) {\n        var addIndex = splice.index;\n        for (; addIndex < splice.index + splice.addedCount; addIndex++) {\n          var model = this.iteratedValue[addIndex];\n          var fragment = undefined;\n          var instanceNodes = instanceCache.get(model);\n          var instanceBindings;\n          if (instanceNodes) {\n            instanceCache.delete(model);\n            instanceBindings = instanceNodes.instanceBindings;\n          } else {\n            instanceBindings = [];\n            if (this.instanceModelFn_)\n              model = this.instanceModelFn_(model);\n\n            if (model !== undefined) {\n              fragment = template.createInstance(model, undefined, delegate,\n                                                 instanceBindings);\n            }\n          }\n\n          this.insertInstanceAt(addIndex, fragment, instanceNodes,\n                                instanceBindings);\n        }\n      }, this);\n\n      instanceCache.forEach(function(instanceNodes) {\n        this.closeInstanceBindings(instanceNodes.instanceBindings);\n      }, this);\n\n      if (this.instancePositionChangedFn_)\n        this.reportInstancesMoved(splices);\n    },\n\n    reportInstanceMoved: function(index) {\n      var previousTerminator = this.getTerminatorAt(index - 1);\n      var terminator = this.getTerminatorAt(index);\n      if (previousTerminator === terminator)\n        return; // instance has zero nodes.\n\n      // We must use the first node of the instance, because any subsequent\n      // nodes may have been generated by sub-templates.\n      // TODO(rafaelw): This is brittle WRT instance mutation -- e.g. if the\n      // first node was removed by script.\n      var templateInstance = previousTerminator.nextSibling.templateInstance;\n      this.instancePositionChangedFn_(templateInstance, index);\n    },\n\n    reportInstancesMoved: function(splices) {\n      var index = 0;\n      var offset = 0;\n      for (var i = 0; i < splices.length; i++) {\n        var splice = splices[i];\n        if (offset != 0) {\n          while (index < splice.index) {\n            this.reportInstanceMoved(index);\n            index++;\n          }\n        } else {\n          index = splice.index;\n        }\n\n        while (index < splice.index + splice.addedCount) {\n          this.reportInstanceMoved(index);\n          index++;\n        }\n\n        offset += splice.addedCount - splice.removed.length;\n      }\n\n      if (offset == 0)\n        return;\n\n      var length = this.terminators.length / 2;\n      while (index < length) {\n        this.reportInstanceMoved(index);\n        index++;\n      }\n    },\n\n    closeInstanceBindings: function(instanceBindings) {\n      for (var i = 0; i < instanceBindings.length; i++) {\n        instanceBindings[i].close();\n      }\n    },\n\n    unobserve: function() {\n      if (!this.arrayObserver)\n        return;\n\n      this.arrayObserver.close();\n      this.arrayObserver = undefined;\n    },\n\n    close: function() {\n      if (this.closed)\n        return;\n      this.unobserve();\n      for (var i = 1; i < this.terminators.length; i += 2) {\n        this.closeInstanceBindings(this.terminators[i]);\n      }\n\n      this.terminators.length = 0;\n      this.closeDeps();\n      this.templateElement_.iterator_ = undefined;\n      this.closed = true;\n    }\n  };\n\n  // Polyfill-specific API.\n  HTMLTemplateElement.forAllTemplatesFrom_ = forAllTemplatesFrom;\n})(this);\n","/*\n  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>\n  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>\n  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>\n  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>\n  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>\n  Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>\n  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>\n  Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>\n  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n(function (global) {\n    'use strict';\n\n    var Token,\n        TokenName,\n        Syntax,\n        Messages,\n        source,\n        index,\n        length,\n        delegate,\n        lookahead,\n        state;\n\n    Token = {\n        BooleanLiteral: 1,\n        EOF: 2,\n        Identifier: 3,\n        Keyword: 4,\n        NullLiteral: 5,\n        NumericLiteral: 6,\n        Punctuator: 7,\n        StringLiteral: 8\n    };\n\n    TokenName = {};\n    TokenName[Token.BooleanLiteral] = 'Boolean';\n    TokenName[Token.EOF] = '<end>';\n    TokenName[Token.Identifier] = 'Identifier';\n    TokenName[Token.Keyword] = 'Keyword';\n    TokenName[Token.NullLiteral] = 'Null';\n    TokenName[Token.NumericLiteral] = 'Numeric';\n    TokenName[Token.Punctuator] = 'Punctuator';\n    TokenName[Token.StringLiteral] = 'String';\n\n    Syntax = {\n        ArrayExpression: 'ArrayExpression',\n        BinaryExpression: 'BinaryExpression',\n        CallExpression: 'CallExpression',\n        ConditionalExpression: 'ConditionalExpression',\n        EmptyStatement: 'EmptyStatement',\n        ExpressionStatement: 'ExpressionStatement',\n        Identifier: 'Identifier',\n        Literal: 'Literal',\n        LabeledStatement: 'LabeledStatement',\n        LogicalExpression: 'LogicalExpression',\n        MemberExpression: 'MemberExpression',\n        ObjectExpression: 'ObjectExpression',\n        Program: 'Program',\n        Property: 'Property',\n        ThisExpression: 'ThisExpression',\n        UnaryExpression: 'UnaryExpression'\n    };\n\n    // Error messages should be identical to V8.\n    Messages = {\n        UnexpectedToken:  'Unexpected token %0',\n        UnknownLabel: 'Undefined label \\'%0\\'',\n        Redeclaration: '%0 \\'%1\\' has already been declared'\n    };\n\n    // Ensure the condition is true, otherwise throw an error.\n    // This is only to have a better contract semantic, i.e. another safety net\n    // to catch a logic error. The condition shall be fulfilled in normal case.\n    // Do NOT use this to enforce a certain condition on any user input.\n\n    function assert(condition, message) {\n        if (!condition) {\n            throw new Error('ASSERT: ' + message);\n        }\n    }\n\n    function isDecimalDigit(ch) {\n        return (ch >= 48 && ch <= 57);   // 0..9\n    }\n\n\n    // 7.2 White Space\n\n    function isWhiteSpace(ch) {\n        return (ch === 32) ||  // space\n            (ch === 9) ||      // tab\n            (ch === 0xB) ||\n            (ch === 0xC) ||\n            (ch === 0xA0) ||\n            (ch >= 0x1680 && '\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\uFEFF'.indexOf(String.fromCharCode(ch)) > 0);\n    }\n\n    // 7.3 Line Terminators\n\n    function isLineTerminator(ch) {\n        return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029);\n    }\n\n    // 7.6 Identifier Names and Identifiers\n\n    function isIdentifierStart(ch) {\n        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)\n            (ch >= 65 && ch <= 90) ||         // A..Z\n            (ch >= 97 && ch <= 122);          // a..z\n    }\n\n    function isIdentifierPart(ch) {\n        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)\n            (ch >= 65 && ch <= 90) ||         // A..Z\n            (ch >= 97 && ch <= 122) ||        // a..z\n            (ch >= 48 && ch <= 57);           // 0..9\n    }\n\n    // 7.6.1.1 Keywords\n\n    function isKeyword(id) {\n        return (id === 'this')\n    }\n\n    // 7.4 Comments\n\n    function skipWhitespace() {\n        while (index < length && isWhiteSpace(source.charCodeAt(index))) {\n           ++index;\n        }\n    }\n\n    function getIdentifier() {\n        var start, ch;\n\n        start = index++;\n        while (index < length) {\n            ch = source.charCodeAt(index);\n            if (isIdentifierPart(ch)) {\n                ++index;\n            } else {\n                break;\n            }\n        }\n\n        return source.slice(start, index);\n    }\n\n    function scanIdentifier() {\n        var start, id, type;\n\n        start = index;\n\n        id = getIdentifier();\n\n        // There is no keyword or literal with only one character.\n        // Thus, it must be an identifier.\n        if (id.length === 1) {\n            type = Token.Identifier;\n        } else if (isKeyword(id)) {\n            type = Token.Keyword;\n        } else if (id === 'null') {\n            type = Token.NullLiteral;\n        } else if (id === 'true' || id === 'false') {\n            type = Token.BooleanLiteral;\n        } else {\n            type = Token.Identifier;\n        }\n\n        return {\n            type: type,\n            value: id,\n            range: [start, index]\n        };\n    }\n\n\n    // 7.7 Punctuators\n\n    function scanPunctuator() {\n        var start = index,\n            code = source.charCodeAt(index),\n            code2,\n            ch1 = source[index],\n            ch2;\n\n        switch (code) {\n\n        // Check for most common single-character punctuators.\n        case 46:   // . dot\n        case 40:   // ( open bracket\n        case 41:   // ) close bracket\n        case 59:   // ; semicolon\n        case 44:   // , comma\n        case 123:  // { open curly brace\n        case 125:  // } close curly brace\n        case 91:   // [\n        case 93:   // ]\n        case 58:   // :\n        case 63:   // ?\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: String.fromCharCode(code),\n                range: [start, index]\n            };\n\n        default:\n            code2 = source.charCodeAt(index + 1);\n\n            // '=' (char #61) marks an assignment or comparison operator.\n            if (code2 === 61) {\n                switch (code) {\n                case 37:  // %\n                case 38:  // &\n                case 42:  // *:\n                case 43:  // +\n                case 45:  // -\n                case 47:  // /\n                case 60:  // <\n                case 62:  // >\n                case 124: // |\n                    index += 2;\n                    return {\n                        type: Token.Punctuator,\n                        value: String.fromCharCode(code) + String.fromCharCode(code2),\n                        range: [start, index]\n                    };\n\n                case 33: // !\n                case 61: // =\n                    index += 2;\n\n                    // !== and ===\n                    if (source.charCodeAt(index) === 61) {\n                        ++index;\n                    }\n                    return {\n                        type: Token.Punctuator,\n                        value: source.slice(start, index),\n                        range: [start, index]\n                    };\n                default:\n                    break;\n                }\n            }\n            break;\n        }\n\n        // Peek more characters.\n\n        ch2 = source[index + 1];\n\n        // Other 2-character punctuators: && ||\n\n        if (ch1 === ch2 && ('&|'.indexOf(ch1) >= 0)) {\n            index += 2;\n            return {\n                type: Token.Punctuator,\n                value: ch1 + ch2,\n                range: [start, index]\n            };\n        }\n\n        if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: ch1,\n                range: [start, index]\n            };\n        }\n\n        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n    }\n\n    // 7.8.3 Numeric Literals\n    function scanNumericLiteral() {\n        var number, start, ch;\n\n        ch = source[index];\n        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),\n            'Numeric literal must start with a decimal digit or a decimal point');\n\n        start = index;\n        number = '';\n        if (ch !== '.') {\n            number = source[index++];\n            ch = source[index];\n\n            // Hex number starts with '0x'.\n            // Octal number starts with '0'.\n            if (number === '0') {\n                // decimal number starts with '0' such as '09' is illegal.\n                if (ch && isDecimalDigit(ch.charCodeAt(0))) {\n                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                }\n            }\n\n            while (isDecimalDigit(source.charCodeAt(index))) {\n                number += source[index++];\n            }\n            ch = source[index];\n        }\n\n        if (ch === '.') {\n            number += source[index++];\n            while (isDecimalDigit(source.charCodeAt(index))) {\n                number += source[index++];\n            }\n            ch = source[index];\n        }\n\n        if (ch === 'e' || ch === 'E') {\n            number += source[index++];\n\n            ch = source[index];\n            if (ch === '+' || ch === '-') {\n                number += source[index++];\n            }\n            if (isDecimalDigit(source.charCodeAt(index))) {\n                while (isDecimalDigit(source.charCodeAt(index))) {\n                    number += source[index++];\n                }\n            } else {\n                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n            }\n        }\n\n        if (isIdentifierStart(source.charCodeAt(index))) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n\n        return {\n            type: Token.NumericLiteral,\n            value: parseFloat(number),\n            range: [start, index]\n        };\n    }\n\n    // 7.8.4 String Literals\n\n    function scanStringLiteral() {\n        var str = '', quote, start, ch, octal = false;\n\n        quote = source[index];\n        assert((quote === '\\'' || quote === '\"'),\n            'String literal must starts with a quote');\n\n        start = index;\n        ++index;\n\n        while (index < length) {\n            ch = source[index++];\n\n            if (ch === quote) {\n                quote = '';\n                break;\n            } else if (ch === '\\\\') {\n                ch = source[index++];\n                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {\n                    switch (ch) {\n                    case 'n':\n                        str += '\\n';\n                        break;\n                    case 'r':\n                        str += '\\r';\n                        break;\n                    case 't':\n                        str += '\\t';\n                        break;\n                    case 'b':\n                        str += '\\b';\n                        break;\n                    case 'f':\n                        str += '\\f';\n                        break;\n                    case 'v':\n                        str += '\\x0B';\n                        break;\n\n                    default:\n                        str += ch;\n                        break;\n                    }\n                } else {\n                    if (ch ===  '\\r' && source[index] === '\\n') {\n                        ++index;\n                    }\n                }\n            } else if (isLineTerminator(ch.charCodeAt(0))) {\n                break;\n            } else {\n                str += ch;\n            }\n        }\n\n        if (quote !== '') {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n\n        return {\n            type: Token.StringLiteral,\n            value: str,\n            octal: octal,\n            range: [start, index]\n        };\n    }\n\n    function isIdentifierName(token) {\n        return token.type === Token.Identifier ||\n            token.type === Token.Keyword ||\n            token.type === Token.BooleanLiteral ||\n            token.type === Token.NullLiteral;\n    }\n\n    function advance() {\n        var ch;\n\n        skipWhitespace();\n\n        if (index >= length) {\n            return {\n                type: Token.EOF,\n                range: [index, index]\n            };\n        }\n\n        ch = source.charCodeAt(index);\n\n        // Very common: ( and ) and ;\n        if (ch === 40 || ch === 41 || ch === 58) {\n            return scanPunctuator();\n        }\n\n        // String literal starts with single quote (#39) or double quote (#34).\n        if (ch === 39 || ch === 34) {\n            return scanStringLiteral();\n        }\n\n        if (isIdentifierStart(ch)) {\n            return scanIdentifier();\n        }\n\n        // Dot (.) char #46 can also start a floating-point number, hence the need\n        // to check the next character.\n        if (ch === 46) {\n            if (isDecimalDigit(source.charCodeAt(index + 1))) {\n                return scanNumericLiteral();\n            }\n            return scanPunctuator();\n        }\n\n        if (isDecimalDigit(ch)) {\n            return scanNumericLiteral();\n        }\n\n        return scanPunctuator();\n    }\n\n    function lex() {\n        var token;\n\n        token = lookahead;\n        index = token.range[1];\n\n        lookahead = advance();\n\n        index = token.range[1];\n\n        return token;\n    }\n\n    function peek() {\n        var pos;\n\n        pos = index;\n        lookahead = advance();\n        index = pos;\n    }\n\n    // Throw an exception\n\n    function throwError(token, messageFormat) {\n        var error,\n            args = Array.prototype.slice.call(arguments, 2),\n            msg = messageFormat.replace(\n                /%(\\d)/g,\n                function (whole, index) {\n                    assert(index < args.length, 'Message reference must be in range');\n                    return args[index];\n                }\n            );\n\n        error = new Error(msg);\n        error.index = index;\n        error.description = msg;\n        throw error;\n    }\n\n    // Throw an exception because of the token.\n\n    function throwUnexpected(token) {\n        throwError(token, Messages.UnexpectedToken, token.value);\n    }\n\n    // Expect the next token to match the specified punctuator.\n    // If not, an exception will be thrown.\n\n    function expect(value) {\n        var token = lex();\n        if (token.type !== Token.Punctuator || token.value !== value) {\n            throwUnexpected(token);\n        }\n    }\n\n    // Return true if the next token matches the specified punctuator.\n\n    function match(value) {\n        return lookahead.type === Token.Punctuator && lookahead.value === value;\n    }\n\n    // Return true if the next token matches the specified keyword\n\n    function matchKeyword(keyword) {\n        return lookahead.type === Token.Keyword && lookahead.value === keyword;\n    }\n\n    function consumeSemicolon() {\n        // Catch the very common case first: immediately a semicolon (char #59).\n        if (source.charCodeAt(index) === 59) {\n            lex();\n            return;\n        }\n\n        skipWhitespace();\n\n        if (match(';')) {\n            lex();\n            return;\n        }\n\n        if (lookahead.type !== Token.EOF && !match('}')) {\n            throwUnexpected(lookahead);\n        }\n    }\n\n    // 11.1.4 Array Initialiser\n\n    function parseArrayInitialiser() {\n        var elements = [];\n\n        expect('[');\n\n        while (!match(']')) {\n            if (match(',')) {\n                lex();\n                elements.push(null);\n            } else {\n                elements.push(parseExpression());\n\n                if (!match(']')) {\n                    expect(',');\n                }\n            }\n        }\n\n        expect(']');\n\n        return delegate.createArrayExpression(elements);\n    }\n\n    // 11.1.5 Object Initialiser\n\n    function parseObjectPropertyKey() {\n        var token;\n\n        skipWhitespace();\n        token = lex();\n\n        // Note: This function is called only from parseObjectProperty(), where\n        // EOF and Punctuator tokens are already filtered out.\n        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {\n            return delegate.createLiteral(token);\n        }\n\n        return delegate.createIdentifier(token.value);\n    }\n\n    function parseObjectProperty() {\n        var token, key;\n\n        token = lookahead;\n        skipWhitespace();\n\n        if (token.type === Token.EOF || token.type === Token.Punctuator) {\n            throwUnexpected(token);\n        }\n\n        key = parseObjectPropertyKey();\n        expect(':');\n        return delegate.createProperty('init', key, parseExpression());\n    }\n\n    function parseObjectInitialiser() {\n        var properties = [];\n\n        expect('{');\n\n        while (!match('}')) {\n            properties.push(parseObjectProperty());\n\n            if (!match('}')) {\n                expect(',');\n            }\n        }\n\n        expect('}');\n\n        return delegate.createObjectExpression(properties);\n    }\n\n    // 11.1.6 The Grouping Operator\n\n    function parseGroupExpression() {\n        var expr;\n\n        expect('(');\n\n        expr = parseExpression();\n\n        expect(')');\n\n        return expr;\n    }\n\n\n    // 11.1 Primary Expressions\n\n    function parsePrimaryExpression() {\n        var type, token, expr;\n\n        if (match('(')) {\n            return parseGroupExpression();\n        }\n\n        type = lookahead.type;\n\n        if (type === Token.Identifier) {\n            expr = delegate.createIdentifier(lex().value);\n        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {\n            expr = delegate.createLiteral(lex());\n        } else if (type === Token.Keyword) {\n            if (matchKeyword('this')) {\n                lex();\n                expr = delegate.createThisExpression();\n            }\n        } else if (type === Token.BooleanLiteral) {\n            token = lex();\n            token.value = (token.value === 'true');\n            expr = delegate.createLiteral(token);\n        } else if (type === Token.NullLiteral) {\n            token = lex();\n            token.value = null;\n            expr = delegate.createLiteral(token);\n        } else if (match('[')) {\n            expr = parseArrayInitialiser();\n        } else if (match('{')) {\n            expr = parseObjectInitialiser();\n        }\n\n        if (expr) {\n            return expr;\n        }\n\n        throwUnexpected(lex());\n    }\n\n    // 11.2 Left-Hand-Side Expressions\n\n    function parseArguments() {\n        var args = [];\n\n        expect('(');\n\n        if (!match(')')) {\n            while (index < length) {\n                args.push(parseExpression());\n                if (match(')')) {\n                    break;\n                }\n                expect(',');\n            }\n        }\n\n        expect(')');\n\n        return args;\n    }\n\n    function parseNonComputedProperty() {\n        var token;\n\n        token = lex();\n\n        if (!isIdentifierName(token)) {\n            throwUnexpected(token);\n        }\n\n        return delegate.createIdentifier(token.value);\n    }\n\n    function parseNonComputedMember() {\n        expect('.');\n\n        return parseNonComputedProperty();\n    }\n\n    function parseComputedMember() {\n        var expr;\n\n        expect('[');\n\n        expr = parseExpression();\n\n        expect(']');\n\n        return expr;\n    }\n\n    function parseLeftHandSideExpression() {\n        var expr, property;\n\n        expr = parsePrimaryExpression();\n\n        while (match('.') || match('[')) {\n            if (match('[')) {\n                property = parseComputedMember();\n                expr = delegate.createMemberExpression('[', expr, property);\n            } else {\n                property = parseNonComputedMember();\n                expr = delegate.createMemberExpression('.', expr, property);\n            }\n        }\n\n        return expr;\n    }\n\n    // 11.3 Postfix Expressions\n\n    var parsePostfixExpression = parseLeftHandSideExpression;\n\n    // 11.4 Unary Operators\n\n    function parseUnaryExpression() {\n        var token, expr;\n\n        if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {\n            expr = parsePostfixExpression();\n        } else if (match('+') || match('-') || match('!')) {\n            token = lex();\n            expr = parseUnaryExpression();\n            expr = delegate.createUnaryExpression(token.value, expr);\n        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {\n            throwError({}, Messages.UnexpectedToken);\n        } else {\n            expr = parsePostfixExpression();\n        }\n\n        return expr;\n    }\n\n    function binaryPrecedence(token) {\n        var prec = 0;\n\n        if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {\n            return 0;\n        }\n\n        switch (token.value) {\n        case '||':\n            prec = 1;\n            break;\n\n        case '&&':\n            prec = 2;\n            break;\n\n        case '==':\n        case '!=':\n        case '===':\n        case '!==':\n            prec = 6;\n            break;\n\n        case '<':\n        case '>':\n        case '<=':\n        case '>=':\n        case 'instanceof':\n            prec = 7;\n            break;\n\n        case 'in':\n            prec = 7;\n            break;\n\n        case '+':\n        case '-':\n            prec = 9;\n            break;\n\n        case '*':\n        case '/':\n        case '%':\n            prec = 11;\n            break;\n\n        default:\n            break;\n        }\n\n        return prec;\n    }\n\n    // 11.5 Multiplicative Operators\n    // 11.6 Additive Operators\n    // 11.7 Bitwise Shift Operators\n    // 11.8 Relational Operators\n    // 11.9 Equality Operators\n    // 11.10 Binary Bitwise Operators\n    // 11.11 Binary Logical Operators\n\n    function parseBinaryExpression() {\n        var expr, token, prec, stack, right, operator, left, i;\n\n        left = parseUnaryExpression();\n\n        token = lookahead;\n        prec = binaryPrecedence(token);\n        if (prec === 0) {\n            return left;\n        }\n        token.prec = prec;\n        lex();\n\n        right = parseUnaryExpression();\n\n        stack = [left, token, right];\n\n        while ((prec = binaryPrecedence(lookahead)) > 0) {\n\n            // Reduce: make a binary expression from the three topmost entries.\n            while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {\n                right = stack.pop();\n                operator = stack.pop().value;\n                left = stack.pop();\n                expr = delegate.createBinaryExpression(operator, left, right);\n                stack.push(expr);\n            }\n\n            // Shift.\n            token = lex();\n            token.prec = prec;\n            stack.push(token);\n            expr = parseUnaryExpression();\n            stack.push(expr);\n        }\n\n        // Final reduce to clean-up the stack.\n        i = stack.length - 1;\n        expr = stack[i];\n        while (i > 1) {\n            expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);\n            i -= 2;\n        }\n\n        return expr;\n    }\n\n\n    // 11.12 Conditional Operator\n\n    function parseConditionalExpression() {\n        var expr, consequent, alternate;\n\n        expr = parseBinaryExpression();\n\n        if (match('?')) {\n            lex();\n            consequent = parseConditionalExpression();\n            expect(':');\n            alternate = parseConditionalExpression();\n\n            expr = delegate.createConditionalExpression(expr, consequent, alternate);\n        }\n\n        return expr;\n    }\n\n    // Simplification since we do not support AssignmentExpression.\n    var parseExpression = parseConditionalExpression;\n\n    // Polymer Syntax extensions\n\n    // Filter ::\n    //   Identifier\n    //   Identifier \"(\" \")\"\n    //   Identifier \"(\" FilterArguments \")\"\n\n    function parseFilter() {\n        var identifier, args;\n\n        identifier = lex();\n\n        if (identifier.type !== Token.Identifier) {\n            throwUnexpected(identifier);\n        }\n\n        args = match('(') ? parseArguments() : [];\n\n        return delegate.createFilter(identifier.value, args);\n    }\n\n    // Filters ::\n    //   \"|\" Filter\n    //   Filters \"|\" Filter\n\n    function parseFilters() {\n        while (match('|')) {\n            lex();\n            parseFilter();\n        }\n    }\n\n    // TopLevel ::\n    //   LabelledExpressions\n    //   AsExpression\n    //   InExpression\n    //   FilterExpression\n\n    // AsExpression ::\n    //   FilterExpression as Identifier\n\n    // InExpression ::\n    //   Identifier, Identifier in FilterExpression\n    //   Identifier in FilterExpression\n\n    // FilterExpression ::\n    //   Expression\n    //   Expression Filters\n\n    function parseTopLevel() {\n        skipWhitespace();\n        peek();\n\n        var expr = parseExpression();\n        if (expr) {\n            if (lookahead.value === ',' || lookahead.value == 'in' &&\n                       expr.type === Syntax.Identifier) {\n                parseInExpression(expr);\n            } else {\n                parseFilters();\n                if (lookahead.value === 'as') {\n                    parseAsExpression(expr);\n                } else {\n                    delegate.createTopLevel(expr);\n                }\n            }\n        }\n\n        if (lookahead.type !== Token.EOF) {\n            throwUnexpected(lookahead);\n        }\n    }\n\n    function parseAsExpression(expr) {\n        lex();  // as\n        var identifier = lex().value;\n        delegate.createAsExpression(expr, identifier);\n    }\n\n    function parseInExpression(identifier) {\n        var indexName;\n        if (lookahead.value === ',') {\n            lex();\n            if (lookahead.type !== Token.Identifier)\n                throwUnexpected(lookahead);\n            indexName = lex().value;\n        }\n\n        lex();  // in\n        var expr = parseExpression();\n        parseFilters();\n        delegate.createInExpression(identifier.name, indexName, expr);\n    }\n\n    function parse(code, inDelegate) {\n        delegate = inDelegate;\n        source = code;\n        index = 0;\n        length = source.length;\n        lookahead = null;\n        state = {\n            labelSet: {}\n        };\n\n        return parseTopLevel();\n    }\n\n    global.esprima = {\n        parse: parse\n    };\n})(this);\n","// Copyright 2013 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function (global) {\n  'use strict';\n\n  // JScript does not have __proto__. We wrap all object literals with\n  // createObject which uses Object.create, Object.defineProperty and\n  // Object.getOwnPropertyDescriptor to create a new object that does the exact\n  // same thing. The main downside to this solution is that we have to extract\n  // all those property descriptors for IE.\n  var createObject = ('__proto__' in {}) ?\n      function(obj) { return obj; } :\n      function(obj) {\n        var proto = obj.__proto__;\n        if (!proto)\n          return obj;\n        var newObject = Object.create(proto);\n        Object.getOwnPropertyNames(obj).forEach(function(name) {\n          Object.defineProperty(newObject, name,\n                               Object.getOwnPropertyDescriptor(obj, name));\n        });\n        return newObject;\n      };\n\n  function prepareBinding(expressionText, name, node, filterRegistry) {\n    var expression;\n    try {\n      expression = getExpression(expressionText);\n      if (expression.scopeIdent &&\n          (node.nodeType !== Node.ELEMENT_NODE ||\n           node.tagName !== 'TEMPLATE' ||\n           (name !== 'bind' && name !== 'repeat'))) {\n        throw Error('as and in can only be used within <template bind/repeat>');\n      }\n    } catch (ex) {\n      console.error('Invalid expression syntax: ' + expressionText, ex);\n      return;\n    }\n\n    return function(model, node, oneTime) {\n      var binding = expression.getBinding(model, filterRegistry, oneTime);\n      if (expression.scopeIdent && binding) {\n        node.polymerExpressionScopeIdent_ = expression.scopeIdent;\n        if (expression.indexIdent)\n          node.polymerExpressionIndexIdent_ = expression.indexIdent;\n      }\n\n      return binding;\n    }\n  }\n\n  // TODO(rafaelw): Implement simple LRU.\n  var expressionParseCache = Object.create(null);\n\n  function getExpression(expressionText) {\n    var expression = expressionParseCache[expressionText];\n    if (!expression) {\n      var delegate = new ASTDelegate();\n      esprima.parse(expressionText, delegate);\n      expression = new Expression(delegate);\n      expressionParseCache[expressionText] = expression;\n    }\n    return expression;\n  }\n\n  function Literal(value) {\n    this.value = value;\n    this.valueFn_ = undefined;\n  }\n\n  Literal.prototype = {\n    valueFn: function() {\n      if (!this.valueFn_) {\n        var value = this.value;\n        this.valueFn_ = function() {\n          return value;\n        }\n      }\n\n      return this.valueFn_;\n    }\n  }\n\n  function IdentPath(name) {\n    this.name = name;\n    this.path = Path.get(name);\n  }\n\n  IdentPath.prototype = {\n    valueFn: function() {\n      if (!this.valueFn_) {\n        var name = this.name;\n        var path = this.path;\n        this.valueFn_ = function(model, observer) {\n          if (observer)\n            observer.addPath(model, path);\n\n          return path.getValueFrom(model);\n        }\n      }\n\n      return this.valueFn_;\n    },\n\n    setValue: function(model, newValue) {\n      if (this.path.length == 1);\n        model = findScope(model, this.path[0]);\n\n      return this.path.setValueFrom(model, newValue);\n    }\n  };\n\n  function MemberExpression(object, property, accessor) {\n    // convert literal computed property access where literal value is a value\n    // path to ident dot-access.\n    if (accessor == '[' &&\n        property instanceof Literal &&\n        Path.get(property.value).valid) {\n      accessor = '.';\n      property = new IdentPath(property.value);\n    }\n\n    this.dynamicDeps = typeof object == 'function' || object.dynamic;\n\n    this.dynamic = typeof property == 'function' ||\n                   property.dynamic ||\n                   accessor == '[';\n\n    this.simplePath =\n        !this.dynamic &&\n        !this.dynamicDeps &&\n        property instanceof IdentPath &&\n        (object instanceof MemberExpression || object instanceof IdentPath);\n\n    this.object = this.simplePath ? object : getFn(object);\n    this.property = accessor == '.' ? property : getFn(property);\n  }\n\n  MemberExpression.prototype = {\n    get fullPath() {\n      if (!this.fullPath_) {\n        var last = this.object instanceof IdentPath ?\n            this.object.name : this.object.fullPath;\n        this.fullPath_ = Path.get(last + '.' + this.property.name);\n      }\n\n      return this.fullPath_;\n    },\n\n    valueFn: function() {\n      if (!this.valueFn_) {\n        var object = this.object;\n\n        if (this.simplePath) {\n          var path = this.fullPath;\n\n          this.valueFn_ = function(model, observer) {\n            if (observer)\n              observer.addPath(model, path);\n\n            return path.getValueFrom(model);\n          };\n        } else if (this.property instanceof IdentPath) {\n          var path = Path.get(this.property.name);\n\n          this.valueFn_ = function(model, observer) {\n            var context = object(model, observer);\n\n            if (observer)\n              observer.addPath(context, path);\n\n            return path.getValueFrom(context);\n          }\n        } else {\n          // Computed property.\n          var property = this.property;\n\n          this.valueFn_ = function(model, observer) {\n            var context = object(model, observer);\n            var propName = property(model, observer);\n            if (observer)\n              observer.addPath(context, propName);\n\n            return context ? context[propName] : undefined;\n          };\n        }\n      }\n      return this.valueFn_;\n    },\n\n    setValue: function(model, newValue) {\n      if (this.simplePath) {\n        this.fullPath.setValueFrom(model, newValue);\n        return newValue;\n      }\n\n      var object = this.object(model);\n      var propName = this.property instanceof IdentPath ? this.property.name :\n          this.property(model);\n      return object[propName] = newValue;\n    }\n  };\n\n  function Filter(name, args) {\n    this.name = name;\n    this.args = [];\n    for (var i = 0; i < args.length; i++) {\n      this.args[i] = getFn(args[i]);\n    }\n  }\n\n  Filter.prototype = {\n    transform: function(value, toModelDirection, filterRegistry, model,\n                        observer) {\n      var fn = filterRegistry[this.name];\n      var context = model;\n      if (fn) {\n        context = undefined;\n      } else {\n        fn = context[this.name];\n        if (!fn) {\n          console.error('Cannot find filter: ' + this.name);\n          return;\n        }\n      }\n\n      // If toModelDirection is falsey, then the \"normal\" (dom-bound) direction\n      // is used. Otherwise, it looks for a 'toModel' property function on the\n      // object.\n      if (toModelDirection) {\n        fn = fn.toModel;\n      } else if (typeof fn.toDOM == 'function') {\n        fn = fn.toDOM;\n      }\n\n      if (typeof fn != 'function') {\n        console.error('No ' + (toModelDirection ? 'toModel' : 'toDOM') +\n                      ' found on' + this.name);\n        return;\n      }\n\n      var args = [value];\n      for (var i = 0; i < this.args.length; i++) {\n        args[i + 1] = getFn(this.args[i])(model, observer);\n      }\n\n      return fn.apply(context, args);\n    }\n  };\n\n  function notImplemented() { throw Error('Not Implemented'); }\n\n  var unaryOperators = {\n    '+': function(v) { return +v; },\n    '-': function(v) { return -v; },\n    '!': function(v) { return !v; }\n  };\n\n  var binaryOperators = {\n    '+': function(l, r) { return l+r; },\n    '-': function(l, r) { return l-r; },\n    '*': function(l, r) { return l*r; },\n    '/': function(l, r) { return l/r; },\n    '%': function(l, r) { return l%r; },\n    '<': function(l, r) { return l<r; },\n    '>': function(l, r) { return l>r; },\n    '<=': function(l, r) { return l<=r; },\n    '>=': function(l, r) { return l>=r; },\n    '==': function(l, r) { return l==r; },\n    '!=': function(l, r) { return l!=r; },\n    '===': function(l, r) { return l===r; },\n    '!==': function(l, r) { return l!==r; },\n    '&&': function(l, r) { return l&&r; },\n    '||': function(l, r) { return l||r; },\n  };\n\n  function getFn(arg) {\n    return typeof arg == 'function' ? arg : arg.valueFn();\n  }\n\n  function ASTDelegate() {\n    this.expression = null;\n    this.filters = [];\n    this.deps = {};\n    this.currentPath = undefined;\n    this.scopeIdent = undefined;\n    this.indexIdent = undefined;\n    this.dynamicDeps = false;\n  }\n\n  ASTDelegate.prototype = {\n    createUnaryExpression: function(op, argument) {\n      if (!unaryOperators[op])\n        throw Error('Disallowed operator: ' + op);\n\n      argument = getFn(argument);\n\n      return function(model, observer) {\n        return unaryOperators[op](argument(model, observer));\n      };\n    },\n\n    createBinaryExpression: function(op, left, right) {\n      if (!binaryOperators[op])\n        throw Error('Disallowed operator: ' + op);\n\n      left = getFn(left);\n      right = getFn(right);\n\n      return function(model, observer) {\n        return binaryOperators[op](left(model, observer),\n                                   right(model, observer));\n      };\n    },\n\n    createConditionalExpression: function(test, consequent, alternate) {\n      test = getFn(test);\n      consequent = getFn(consequent);\n      alternate = getFn(alternate);\n\n      return function(model, observer) {\n        return test(model, observer) ?\n            consequent(model, observer) : alternate(model, observer);\n      }\n    },\n\n    createIdentifier: function(name) {\n      var ident = new IdentPath(name);\n      ident.type = 'Identifier';\n      return ident;\n    },\n\n    createMemberExpression: function(accessor, object, property) {\n      var ex = new MemberExpression(object, property, accessor);\n      if (ex.dynamicDeps)\n        this.dynamicDeps = true;\n      return ex;\n    },\n\n    createLiteral: function(token) {\n      return new Literal(token.value);\n    },\n\n    createArrayExpression: function(elements) {\n      for (var i = 0; i < elements.length; i++)\n        elements[i] = getFn(elements[i]);\n\n      return function(model, observer) {\n        var arr = []\n        for (var i = 0; i < elements.length; i++)\n          arr.push(elements[i](model, observer));\n        return arr;\n      }\n    },\n\n    createProperty: function(kind, key, value) {\n      return {\n        key: key instanceof IdentPath ? key.name : key.value,\n        value: value\n      };\n    },\n\n    createObjectExpression: function(properties) {\n      for (var i = 0; i < properties.length; i++)\n        properties[i].value = getFn(properties[i].value);\n\n      return function(model, observer) {\n        var obj = {};\n        for (var i = 0; i < properties.length; i++)\n          obj[properties[i].key] = properties[i].value(model, observer);\n        return obj;\n      }\n    },\n\n    createFilter: function(name, args) {\n      this.filters.push(new Filter(name, args));\n    },\n\n    createAsExpression: function(expression, scopeIdent) {\n      this.expression = expression;\n      this.scopeIdent = scopeIdent;\n    },\n\n    createInExpression: function(scopeIdent, indexIdent, expression) {\n      this.expression = expression;\n      this.scopeIdent = scopeIdent;\n      this.indexIdent = indexIdent;\n    },\n\n    createTopLevel: function(expression) {\n      this.expression = expression;\n    },\n\n    createThisExpression: notImplemented\n  }\n\n  function ConstantObservable(value) {\n    this.value_ = value;\n  }\n\n  ConstantObservable.prototype = {\n    open: function() { return this.value_; },\n    discardChanges: function() { return this.value_; },\n    deliver: function() {},\n    close: function() {},\n  }\n\n  function Expression(delegate) {\n    this.scopeIdent = delegate.scopeIdent;\n    this.indexIdent = delegate.indexIdent;\n\n    if (!delegate.expression)\n      throw Error('No expression found.');\n\n    this.expression = delegate.expression;\n    getFn(this.expression); // forces enumeration of path dependencies\n\n    this.filters = delegate.filters;\n    this.dynamicDeps = delegate.dynamicDeps;\n  }\n\n  Expression.prototype = {\n    getBinding: function(model, filterRegistry, oneTime) {\n      if (oneTime)\n        return this.getValue(model, undefined, filterRegistry);\n\n      var observer = new CompoundObserver();\n      this.getValue(model, observer, filterRegistry);  // captures deps.\n      var self = this;\n\n      function valueFn() {\n        if (self.dynamicDeps)\n          observer.startReset();\n\n        var value = self.getValue(model,\n                                  self.dynamicDeps ? observer : undefined,\n                                  filterRegistry);\n        if (self.dynamicDeps)\n          observer.finishReset();\n\n        return value;\n      }\n\n      function setValueFn(newValue) {\n        self.setValue(model, newValue, filterRegistry);\n        return newValue;\n      }\n\n      return new ObserverTransform(observer, valueFn, setValueFn, true);\n    },\n\n    getValue: function(model, observer, filterRegistry) {\n      var value = getFn(this.expression)(model, observer);\n      for (var i = 0; i < this.filters.length; i++) {\n        value = this.filters[i].transform(value, false, filterRegistry, model,\n                                          observer);\n      }\n\n      return value;\n    },\n\n    setValue: function(model, newValue, filterRegistry) {\n      var count = this.filters ? this.filters.length : 0;\n      while (count-- > 0) {\n        newValue = this.filters[count].transform(newValue, true, filterRegistry,\n                                                 model);\n      }\n\n      if (this.expression.setValue)\n        return this.expression.setValue(model, newValue);\n    }\n  }\n\n  /**\n   * Converts a style property name to a css property name. For example:\n   * \"WebkitUserSelect\" to \"-webkit-user-select\"\n   */\n  function convertStylePropertyName(name) {\n    return String(name).replace(/[A-Z]/g, function(c) {\n      return '-' + c.toLowerCase();\n    });\n  }\n\n  function isEventHandler(name) {\n    return name[0] === 'o' &&\n           name[1] === 'n' &&\n           name[2] === '-';\n  }\n\n  var mixedCaseEventTypes = {};\n  [\n    'webkitAnimationStart',\n    'webkitAnimationEnd',\n    'webkitTransitionEnd',\n    'DOMFocusOut',\n    'DOMFocusIn',\n    'DOMMouseScroll'\n  ].forEach(function(e) {\n    mixedCaseEventTypes[e.toLowerCase()] = e;\n  });\n\n  var parentScopeName = '@' + Math.random().toString(36).slice(2);\n\n  // Single ident paths must bind directly to the appropriate scope object.\n  // I.e. Pushed values in two-bindings need to be assigned to the actual model\n  // object.\n  function findScope(model, prop) {\n    while (model[parentScopeName] &&\n           !Object.prototype.hasOwnProperty.call(model, prop)) {\n      model = model[parentScopeName];\n    }\n\n    return model;\n  }\n\n  function resolveEventReceiver(model, path, node) {\n    if (path.length == 0)\n      return undefined;\n\n    if (path.length == 1)\n      return findScope(model, path[0]);\n\n    for (var i = 0; model != null && i < path.length - 1; i++) {\n      model = model[path[i]];\n    }\n\n    return model;\n  }\n\n  function prepareEventBinding(path, name, polymerExpressions) {\n    var eventType = name.substring(3);\n    eventType = mixedCaseEventTypes[eventType] || eventType;\n\n    return function(model, node, oneTime) {\n      var fn, receiver, handler;\n      if (typeof polymerExpressions.resolveEventHandler == 'function') {\n        handler = function(e) {\n          fn = fn || polymerExpressions.resolveEventHandler(model, path, node);\n          fn(e, e.detail, e.currentTarget);\n\n          if (Platform && typeof Platform.flush == 'function')\n            Platform.flush();\n        };\n      } else {\n        handler = function(e) {\n          fn = fn || path.getValueFrom(model);\n          receiver = receiver || resolveEventReceiver(model, path, node);\n\n          fn.apply(receiver, [e, e.detail, e.currentTarget]);\n\n          if (Platform && typeof Platform.flush == 'function')\n            Platform.flush();\n        };\n      }\n\n      node.addEventListener(eventType, handler);\n\n      if (oneTime)\n        return;\n\n      function bindingValue() {\n        return '{{ ' + path + ' }}';\n      }\n\n      return {\n        open: bindingValue,\n        discardChanges: bindingValue,\n        close: function() {\n          node.removeEventListener(eventType, handler);\n        }\n      };\n    }\n  }\n\n  function PolymerExpressions() {}\n\n  PolymerExpressions.prototype = {\n    // \"built-in\" filters\n    styleObject: function(value) {\n      var parts = [];\n      for (var key in value) {\n        parts.push(convertStylePropertyName(key) + ': ' + value[key]);\n      }\n      return parts.join('; ');\n    },\n\n    tokenList: function(value) {\n      var tokens = [];\n      for (var key in value) {\n        if (value[key])\n          tokens.push(key);\n      }\n      return tokens.join(' ');\n    },\n\n    // binding delegate API\n    prepareInstancePositionChanged: function(template) {\n      var indexIdent = template.polymerExpressionIndexIdent_;\n      if (!indexIdent)\n        return;\n\n      return function(templateInstance, index) {\n        templateInstance.model[indexIdent] = index;\n      };\n    },\n\n    prepareBinding: function(pathString, name, node) {\n      var path = Path.get(pathString);\n      if (isEventHandler(name)) {\n        if (!path.valid) {\n          console.error('on-* bindings must be simple path expressions');\n          return;\n        }\n\n        return prepareEventBinding(path, name, this);\n      }\n\n      if (path.valid) {\n        if (path.length == 1) {\n          return function(model, node, oneTime) {\n            if (oneTime)\n              return path.getValueFrom(model);\n\n            var scope = findScope(model, path[0]);\n            return new PathObserver(scope, path);\n          }\n        }\n\n        return; // bail out early if pathString is simple path.\n      }\n\n      return prepareBinding(pathString, name, node, this);\n    },\n\n    prepareInstanceModel: function(template) {\n      var scopeName = template.polymerExpressionScopeIdent_;\n      if (!scopeName)\n        return;\n\n      var parentScope = template.templateInstance ?\n          template.templateInstance.model :\n          template.model;\n\n      var indexName = template.polymerExpressionIndexIdent_;\n\n      return function(model) {\n        var scope = Object.create(parentScope);\n        scope[scopeName] = model;\n        scope[indexName] = undefined;\n        scope[parentScopeName] = parentScope;\n        return scope;\n      };\n    }\n  };\n\n  global.PolymerExpressions = PolymerExpressions;\n  if (global.exposeGetExpression)\n    global.getExpression_ = getExpression;\n\n  global.PolymerExpressions.prepareEventBinding = prepareEventBinding;\n})(this);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n// inject style sheet\nvar style = document.createElement('style');\nstyle.textContent = 'template {display: none !important;} /* injected by platform.js */';\nvar head = document.querySelector('head');\nhead.insertBefore(style, head.firstChild);\n\n// flush (with logging)\nvar flushing;\nfunction flush() {\n  if (!flushing) {\n    flushing = true;\n    scope.endOfMicrotask(function() {\n      flushing = false;\n      logFlags.data && console.group('Platform.flush()');\n      scope.performMicrotaskCheckpoint();\n      logFlags.data && console.groupEnd();\n    });\n  }\n};\n\n// polling dirty checker\nvar FLUSH_POLL_INTERVAL = 125;\nwindow.addEventListener('WebComponentsReady', function() {\n  flush();\n  // flush periodically if platform does not have object observe.\n  if (!Observer.hasObjectObserve) {\n    scope.flushPoll = setInterval(flush, FLUSH_POLL_INTERVAL);\n  }\n});\n\nif (window.CustomElements && !CustomElements.useNative) {\n  var originalImportNode = Document.prototype.importNode;\n  Document.prototype.importNode = function(node, deep) {\n    var imported = originalImportNode.call(this, node, deep);\n    CustomElements.upgradeAll(imported);\n    return imported;\n  }\n}\n\n// exports\nscope.flush = flush;\n\n})(window.Platform);\n\n"]}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/.bower.json
deleted file mode 100644
index 9830dd6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/.bower.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "polymer-localstorage",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/polymer-localstorage",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "19e87468b2a977bf79db60db247e0b4e8672e920"
-  },
-  "_source": "git://github.com/Polymer/polymer-localstorage.git",
-  "_target": "*",
-  "_originalSource": "Polymer/polymer-localstorage"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/bower.json
deleted file mode 100644
index 1006bc1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "name": "polymer-localstorage",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/demo.html
deleted file mode 100644
index 139675b..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/demo.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>polymer-localstorage</title>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="polymer-localstorage.html">
-  <link rel="import" href="../polymer-ui-toggle-button/polymer-ui-toggle-button.html">
-</head>
-<body>
-  <polymer-element name="x-test1">
-    <template>
-      string entered below will be stored in localStorage and automatically retrived from localStorage when the page is reloaded<br>
-      <input value="{{value}}">
-      <polymer-localstorage name="polymer-localstorage-x-test1" value="{{value}}"></polymer-localstorage>
-    </template>
-    <script>
-      Polymer('x-test1');
-    </script>
-  </polymer-element>
-  
-  <x-test1></x-test1>
-  <br><br>
-  
-  <polymer-element name="x-test2">
-    <template>
-      <polymer-ui-toggle-button value="{{mode}}"></polymer-ui-toggle-button>
-      <polymer-localstorage name="polymer-localstorage-x-test2" value="{{mode}}"></polymer-localstorage>
-    </template>
-    <script>
-      Polymer('x-test2', {
-        mode: false
-      });
-    </script>
-  </polymer-element>
-  
-  <x-test2></x-test2>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/polymer-localstorage.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/polymer-localstorage.html
deleted file mode 100644
index 0bfc203..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/polymer-localstorage.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
-/**
- * Element access to localStorage.  The "name" property
- * is the key to the data ("value" property) stored in localStorage.
- *
- * polymer-localstorage automatically saves the value to localStorage when
- * value is changed.  Note that if value is an object auto-save will be
- * triggered only when value is a different instance.
- *
- * Example:
- *
- *     <polymer-localstorage name="my-app-storage" value="{{value}}"></polymer-localstorage>
- *
- * @class polymer-localstorage
- * @blurb Element access to localStorage.
- * @snap http://polymer.github.io/polymer-localstorage/snap.png
- * @author The Polymer Authors
- * @categories Data
- *
- */
-/**
- * Fired after it is loaded from localStorage.
- * 
- * @event polymer-localstorage-load
- */
--->
-<link rel="import" href="../polymer/polymer.html">
-
-<polymer-element name="polymer-localstorage" attributes="name value useRaw autoSaveDisabled">
-  <template>
-    <style>
-      :host {
-        display: none;
-      }
-    </style>
-  </template>
-  <script>
-    Polymer('polymer-localstorage', {
-      /**
-       * The key to the data stored in localStorage.
-       *
-       * @attribute name
-       * @type string
-       * @default null
-       */
-      name: '',
-      /**
-       * The data associated with the specified name.
-       *
-       * @attribute value
-       * @type object
-       * @default null
-       */
-      value: null,
-      /**
-       * If true, the value is stored and retrieved without JSON processing.
-       *
-       * @attribute useRaw
-       * @type boolean
-       * @default false
-       */
-      useRaw: false,
-      /**
-       * If true, auto save is disabled.
-       *
-       * @attribute autoSaveDisabled
-       * @type boolean
-       * @default false
-       */
-      autoSaveDisabled: false,
-      enteredView: function() {
-        // wait for bindings are all setup
-        this.async('load');
-      },
-      valueChanged: function() {
-        if (this.loaded && !this.autoSaveDisabled) {
-          this.save();
-        }
-      },
-      load: function() {
-        var v = localStorage.getItem(this.name);
-        if (this.useRaw) {
-          this.value = v;
-        } else {
-          // localStorage has a flaw that makes it difficult to determine
-          // if a key actually exists or not (getItem returns null if the
-          // key doesn't exist, which is not distinguishable from a stored
-          // null value)
-          // however, if not `useRaw`, an (unparsed) null value unambiguously
-          // signals that there is no value in storage (a stored null value would
-          // be escaped, i.e. "null")
-          // in this case we save any non-null current (default) value
-          if (v === null) {
-            if (this.value !== null) {
-              this.save();
-            }
-          } else {
-            try {
-              v = JSON.parse(v);
-            } catch(x) {
-            }
-            this.value = v;
-          }
-        }
-        this.loaded = true;
-        this.asyncFire('polymer-localstorage-load');
-      },
-      /** 
-       * Saves the value to localStorage.
-       *
-       * @method save
-       */
-      save: function() {
-        var v = this.useRaw ? this.value : JSON.stringify(this.value);
-        localStorage.setItem(this.name, v);
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/html/polymer-localstorage.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/html/polymer-localstorage.html
deleted file mode 100644
index 7234dbe..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/html/polymer-localstorage.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-localstorage</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-localstorage.html">
-</head>
-<body>
-
-  <polymer-localstorage id="localstorage" name="polymer-localstorage-test" useRaw></polymer-localstorage>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('#localstorage');
-      var m = 'hello wold';
-      window.localStorage.setItem(s.name, m);
-      s.load();
-      assert.equal(s.value, m);
-      s.value = 'goodbye';
-      assert.equal(window.localStorage.getItem(s.name), m);
-      done();
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/js/polymer-localstorage.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/js/polymer-localstorage.js
deleted file mode 100644
index 9bba7a1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/js/polymer-localstorage.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Copyright 2013 The Polymer Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-
-htmlSuite('polymer-localstorage', function() {
-  htmlTest('html/polymer-localstorage.html');
-});
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/runner.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/runner.html
deleted file mode 100644
index 65ef121..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/runner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>polymer-localstorage Test Runner (Mocha)</title>
-    <meta charset="UTF-8">
-    <!-- -->
-    <link rel="stylesheet" href="../../tools/test/mocha/mocha.css" />
-    <script src="../../tools/test/mocha/mocha.js"></script>
-    <script src="../../tools/test/chai/chai.js"></script>
-    <script src="../../tools/test/mocha-htmltest.js"></script>
-    <!-- -->
-    <script src="../../platform/platform.js"></script>
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script>
-      mocha.setup({ui: 'tdd', slow: 1000, htmlbase: ''});
-    </script>
-    <!-- -->
-    <script src="js/polymer-localstorage.js"></script>
-    <!-- -->
-    <script>
-      mocha.run();
-    </script>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/.bower.json
deleted file mode 100644
index dd32aa8..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/.bower.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "polymer-selection",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/polymer-selection",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "414b5314477367acb821fc515279f18bc66e4897"
-  },
-  "_source": "git://github.com/Polymer/polymer-selection.git",
-  "_target": "0.2.1",
-  "_originalSource": "Polymer/polymer-selection"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/bower.json
deleted file mode 100644
index 118451d..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "name": "polymer-selection",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/demo.html
deleted file mode 100644
index c7994a2..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/demo.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>Selection</title>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="polymer-selection.html">
-</head>
-<body>
-<polymer-element name="selection-example">
-  <template>
-    <style>
-      /* @polyfill ul > * */
-      ::-webkit-distributed(> *) {
-        cursor: pointer;
-      }
-
-      /* @polyfill ul > .selected */
-      ::-webkit-distributed(> .selected) {
-        font-weight: bold;
-        font-style: italic;
-      }
-    </style>
-    <ul on-tap="{{itemTapAction}}">
-      <content></content>
-    </ul>
-    <polymer-selection id="selection" multi on-polymer-select="{{selectAction}}"></polymer-selection>
-    </template>
-    <script>
-    Polymer('selection-example', {
-      itemTapAction: function(e) {
-        this.$.selection.select(e.target);
-      },
-      selectAction: function(e, detail) {
-        detail.item.classList.toggle('selected', detail.isSelected);
-      }
-    });
-    </script>
-  </polymer-element>
-
-  <selection-example>
-    <li>Red</li>
-    <li>Green</li>
-    <li>Blue</li>
-  </selection-example>
-  
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/polymer-selection.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/polymer-selection.html
deleted file mode 100644
index d29fae4..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/polymer-selection.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
--->
-<!--
-/**
- * The polymer-selection element is used to manage selection state. It has no
- * visual appearance and is typically used in conjuneciton with another element.
- * For example, <a href="polymer-selector.html">polymer-selector</a>
- * use a polymer-selection to manage selection.
- *
- * To mark an item as selected, call the select(item) method on 
- * polymer-selection. Notice that the item itself is an argument to this method.
- * The polymer-selection element manages selection state for any given set of
- * items. When an item is selected, the `polymer-select` event is fired.
- * The attribute "multi" indicates if multiple items can be selected at once.
- * 
- * Example:
- *
- *     <polymer-element name="selection-example">
- *        <template>
- *          <style>
- *            ::-webkit-distributed(> .selected) {
- *              font-weight: bold;
- *              font-style: italic;
- *            }
- *          </style>
- *          <ul on-tap="{{itemTapAction}}">
- *            <content></content>
- *          </ul>
- *          <polymer-selection id="selection" multi on-polymer-select="{{selectAction}}"></polymer-selection>
- *        </template>
- *        <script>
- *          Polymer('selection-example', {
- *            itemTapAction: function(e) {
- *              this.$.selection.select(e.target);
- *            },
- *            selectAction: function(e, detail) {
- *              detail.item.classList.toggle('selected', detail.isSelected);
- *            }
- *          });
- *        </script>
- *     </polymer-element>
- *
- *     <selection-example>
- *       <li>Red</li>
- *       <li>Green</li>
- *       <li>Blue</li>
- *     </selection-example>
- *
- * @class polymer-selection
- */
- /**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- * 
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
--->
-<link rel="import" href="../polymer/polymer.html">
-
-<polymer-element name="polymer-selection" attributes="multi">
-  <template>
-    <style>
-      :host {
-        display: none !important;
-      }
-    </style>
-  </template>
-  <script>
-    Polymer('polymer-selection', {
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      ready: function() {
-        this.clear();
-      },
-      clear: function() {
-        this.selection = [];
-      },
-      /**
-       * Retrieves the selected item(s).
-       * @method getSelection
-       * @returns Returns the selected item(s). If the multi property is true,
-       * getSelection will return an array, otherwise it will return 
-       * the selected item or undefined if there is no selection.
-      */
-      getSelection: function() {
-        return this.multi ? this.selection : this.selection[0];
-      },
-      /**
-       * Indicates if a given item is selected.
-       * @method isSelected
-       * @param {any} item The item whose selection state should be checked.
-       * @returns Returns true if `item` is selected.
-      */
-      isSelected: function(item) {
-        return this.selection.indexOf(item) >= 0;
-      },
-      setItemSelected: function(item, isSelected) {
-        if (item !== undefined && item !== null) {
-          if (isSelected) {
-            this.selection.push(item);
-          } else {
-            var i = this.selection.indexOf(item);
-            if (i >= 0) {
-              this.selection.splice(i, 1);
-            }
-          }
-          this.fire("polymer-select", {isSelected: isSelected, item: item});
-        }
-      },
-      /**
-       * Set the selection state for a given `item`. If the multi property
-       * is true, then the selected state of `item` will be toggled; otherwise
-       * the `item` will be selected.
-       * @method select
-       * @param {any} item: The item to select.
-      */
-      select: function(item) {
-        if (this.multi) {
-          this.toggle(item);
-        } else if (this.getSelection() !== item) {
-          this.setItemSelected(this.getSelection(), false);
-          this.setItemSelected(item, true);
-        }
-      },
-      /**
-       * Toggles the selection state for `item`.
-       * @method toggle
-       * @param {any} item: The item to toggle.
-      */
-      toggle: function(item) {
-        this.setItemSelected(item, !this.isSelected(item));
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection-multi.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection-multi.html
deleted file mode 100644
index ebc02f6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection-multi.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selection-multi</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selection.html">
-</head>
-<body>
-
-  <polymer-selection multi></polymer-selection>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('polymer-selection');
-      s.addEventListener("polymer-select", function(event) {
-        if (test === 1) {
-          // check test1
-          assert.isTrue(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item1)');
-          assert.isTrue(s.isSelected(event.detail.item));
-          assert.equal(s.getSelection().length, 1);
-          // test2
-          test++;
-          s.select('(item2)');
-        } else if (test === 2) {
-          // check test2
-          assert.isTrue(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item2)');
-          assert.isTrue(s.isSelected(event.detail.item));
-          assert.equal(s.getSelection().length, 2);
-          done();
-        }
-      });
-      // test1
-      var test = 1;
-      s.select('(item1)');
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection.html
deleted file mode 100644
index 1149890..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selection</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selection.html">
-</head>
-<body>
-
-  <polymer-selection></polymer-selection>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('polymer-selection');
-      s.addEventListener("polymer-select", function(event) {
-        if (test === 1) {
-          // check test1
-          assert.isTrue(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item)');
-          assert.isTrue(s.isSelected(event.detail.item));
-          assert.isFalse(s.isSelected('(some_item_not_selected)'));
-          // test2
-          test++;
-          s.select(null);
-        } else if (test === 2) {
-          // check test2
-          assert.isFalse(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item)');
-          assert.isFalse(s.isSelected(event.detail.item));
-          done();
-        }
-      });
-      // test1
-      var test = 1;
-      s.select('(item)');
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/js/polymer-selection.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/js/polymer-selection.js
deleted file mode 100644
index 023e495..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/js/polymer-selection.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*

- * Copyright 2013 The Polymer Authors. All rights reserved.

- * Use of this source code is governed by a BSD-style

- * license that can be found in the LICENSE file.

- */

-

-htmlSuite('polymer-selection', function() {

-  htmlTest('html/polymer-selection.html');

-  htmlTest('html/polymer-selection-multi.html');

-});
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/runner.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/runner.html
deleted file mode 100644
index 5667519..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/runner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>polymer-selection Test Runner (Mocha)</title>
-    <meta charset="UTF-8">
-    <!-- -->
-    <link rel="stylesheet" href="../../tools/test/mocha/mocha.css" />
-    <script src="../../tools/test/mocha/mocha.js"></script>
-    <script src="../../tools/test/chai/chai.js"></script>
-    <script src="../../tools/test/mocha-htmltest.js"></script>
-    <!-- -->
-    <script src="../../platform/platform.js"></script>
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script>
-      mocha.setup({ui: 'tdd', slow: 1000, htmlbase: ''});
-    </script>
-    <!-- -->
-    <script src="js/polymer-selection.js"></script>
-    <!-- -->
-    <script>
-      mocha.run();
-    </script>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/.bower.json
deleted file mode 100644
index 726b021..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/.bower.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "polymer-selector",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1",
-    "polymer-selection": "Polymer/polymer-selection#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/polymer-selector",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "cd84d37c050e2badb90fd621061866bcdde48515"
-  },
-  "_source": "git://github.com/Polymer/polymer-selector.git",
-  "_target": "*",
-  "_originalSource": "Polymer/polymer-selector"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/README.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/README.md
deleted file mode 100644
index ed4a600..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-polymer-selector
-================
-
-[LICENSE](https://raw.github.com/Polymer/polymer/master/LICENSE)
-
-[PATENTS](https://raw.github.com/Polymer/polymer/master/PATENTS)
-
-[CONTRIBUTING](https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md)
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/bower.json
deleted file mode 100644
index f9d24cd..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/bower.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "name": "polymer-selector",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1",
-    "polymer-selection": "Polymer/polymer-selection#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/demo.html
deleted file mode 100644
index 730de55..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/demo.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>Selector</title>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="polymer-selector.html">
-</head>
-<body unresolved>
-  <polymer-element name="selector-examples">
-    <template>
-      <style>
-        .list {
-          display: block;
-          border: 1px solid #ccc;
-          border-bottom: none;
-          background: #666;
-          color: white;
-          list-style: none;
-          margin: 0;
-          padding: 0;
-        }
-        
-        .list > * {
-          height: 40px;
-          line-height: 40px;
-          padding: 0 20px;
-          border-bottom: 1px solid #ccc;
-        }
-        
-        .list > *.polymer-selected {
-          background: #333;
-        }
-        
-        li {
-          height: 30px;
-        }
-        
-        li.polymer-selected:after {
-          content: "\2713";
-          position: absolute;
-          padding-left: 10px;
-        }
-      </style>
-      
-      <h2>basic</h2>
-      <polymer-selector class="list" selected="0">
-        <div>Item 0</div>
-        <div>Item 1</div>
-        <div>Item 2</div>
-        <div>Item 3</div>
-        <div>Item 4</div>
-      </polymer-selector>
-      
-      <h2>multi-selection</h2>
-      <polymer-selector class="list" selected="{{multiSelected}}" multi>
-        <div>Item 0</div>
-        <div>Item 1</div>
-        <div>Item 2</div>
-        <div>Item 3</div>
-        <div>Item 4</div>
-      </polymer-selector>
-      
-      <h2>list</h2>
-      <polymer-selector target="{{$.list}}" selected="0"></polymer-selector>
-      <ul id="list">
-        <li>Item 0</li>
-        <li>Item 1</li>
-        <li>Item 2</li>
-        <li>Item 3</li>
-        <li>Item 4</li>
-      </ul>
-      
-      <h2>binding of a group of radio buttons to a variable</h2>
-      <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=radio]" 
-          selected="{{color}}" valueattr="value" selectedProperty="checked" 
-          activateEvent="change"></polymer-selector>
-      <form id="myForm">
-        <label><input type="radio" name="color" value="red"> Red</label> <br>
-        <label><input type="radio" name="color" value="green"> Green</label> <br>
-        <label><input type="radio" name="color" value="blue"> Blue</label> <br>
-        <p>color = {{color}}</p>
-      </form>
-      
-    </template>
-
-    <script>
-      Polymer('selector-examples', {
-        ready: function() {
-          this.multiSelected = [1, 3];
-          this.color = 'green';
-        }
-      });
-    </script>
-  </polymer-element>
-  
-  <selector-examples></selector-examples>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/docs.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/docs.json
deleted file mode 100644
index 9f4f0a1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/docs.json
+++ /dev/null
@@ -1,224 +0,0 @@
-{
-    "project": {
-        "name": "Docs",
-        "description": "Docs"
-    },
-    "files": {
-        "../../polymer-selector/polymer-selector.html": {
-            "name": "../../polymer-selector/polymer-selector.html",
-            "modules": {
-                "Polymer Elements": 1
-            },
-            "classes": {
-                "polymer-selector": 1
-            },
-            "fors": {},
-            "namespaces": {}
-        }
-    },
-    "modules": {
-        "Polymer Elements": {
-            "name": "Polymer Elements",
-            "submodules": {},
-            "classes": {
-                "polymer-selector": 1
-            },
-            "fors": {},
-            "namespaces": {},
-            "tag": "module",
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 10
-        }
-    },
-    "classes": {
-        "polymer-selector": {
-            "name": "polymer-selector",
-            "shortname": "polymer-selector",
-            "classitems": [],
-            "plugins": [],
-            "extensions": [],
-            "plugin_for": [],
-            "extension_for": [],
-            "module": "Polymer Elements",
-            "namespace": "",
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 10,
-            "description": "polymer-selector is used to manage a list of elements that can be selected.\nThe attribute \"selected\" indicates which item element is being selected.\nThe attribute \"multi\" indicates if multiple items can be selected at once.\nTapping on the item element would fire \"polymer-activate\" event. Use\n\"polymer-select\" event to listen for selection changes.\n\nExample:\n\n    <polymer-selector selected=\"0\">\n      <div>Item 1</div>\n      <div>Item 2</div>\n      <div>Item 3</div>\n    </polymer-selector>\n\npolymer-selector is not styled.  So one needs to use \"polymer-selected\" CSS\nclass to style the selected element.\n\n    <style>\n      .item.polymer-selected {\n        background: #eee;\n      }\n    </style>\n    ...\n    <polymer-selector>\n      <div class=\"item\">Item 1</div>\n      <div class=\"item\">Item 2</div>\n      <div class=\"item\">Item 3</div>\n    </polymer-selector>"
-        }
-    },
-    "classitems": [
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 42,
-            "description": "Fired when an item's selection state is changed. This event is fired both\nwhen an item is selected or deselected. The `isSelected` detail property\ncontains the selection state.",
-            "itemtype": "event",
-            "name": "polymer-select",
-            "params": [
-                {
-                    "name": "detail",
-                    "description": "",
-                    "type": "Object",
-                    "props": [
-                        {
-                            "name": "isSelected",
-                            "description": "true for selection and false for deselection",
-                            "type": "Boolean"
-                        },
-                        {
-                            "name": "item",
-                            "description": "the item element",
-                            "type": "Object"
-                        }
-                    ]
-                }
-            ],
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 52,
-            "description": "Fired when an item element is tapped.",
-            "itemtype": "event",
-            "name": "polymer-activate",
-            "params": [
-                {
-                    "name": "detail",
-                    "description": "",
-                    "type": "Object",
-                    "props": [
-                        {
-                            "name": "item",
-                            "description": "the item element",
-                            "type": "Object"
-                        }
-                    ]
-                }
-            ],
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 71,
-            "description": "Gets or sets the selected element.  Default to use the index\nof the item element.\n\nIf you want a specific attribute value of the element to be\nused instead of index, set \"valueattr\" to that attribute name.\n\nExample:\n\n    <polymer-selector valueattr=\"label\" selected=\"foo\">\n      <div label=\"foo\"></div>\n      <div label=\"bar\"></div>\n      <div label=\"zot\"></div>\n    </polymer-selector>\n\nIn multi-selection this should be an array of values.\n\nExample:\n\n    <polymer-selector id=\"selector\" valueattr=\"label\" multi>\n      <div label=\"foo\"></div>\n      <div label=\"bar\"></div>\n      <div label=\"zot\"></div>\n    </polymer-selector>\n\n    this.$.selector.selected = ['foo', 'zot'];",
-            "itemtype": "attribute",
-            "name": "selected",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 103,
-            "description": "If true, multiple selections are allowed.",
-            "itemtype": "attribute",
-            "name": "multi",
-            "type": "boolean",
-            "default": "false",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 111,
-            "description": "Specifies the attribute to be used for \"selected\" attribute.",
-            "itemtype": "attribute",
-            "name": "valueattr",
-            "type": "string",
-            "default": "'name'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 119,
-            "description": "Specifies the CSS class to be used to add to the selected element.",
-            "itemtype": "attribute",
-            "name": "selectedClass",
-            "type": "string",
-            "default": "'polymer-selected'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 127,
-            "description": "Specifies the property to be used to set on the selected element\nto indicate its active state.",
-            "itemtype": "attribute",
-            "name": "selectedProperty",
-            "type": "string",
-            "default": "'active'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 136,
-            "description": "Returns the currently selected element. In multi-selection this returns\nan array of selected elements.",
-            "itemtype": "attribute",
-            "name": "selectedItem",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 145,
-            "description": "In single selection, this returns the model associated with the\nselected element.",
-            "itemtype": "attribute",
-            "name": "selectedModel",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 154,
-            "description": "In single selection, this returns the selected index.",
-            "itemtype": "attribute",
-            "name": "selectedIndex",
-            "type": "number",
-            "default": "-1",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 162,
-            "description": "The target element that contains items.  If this is not set \npolymer-selector is the container.",
-            "itemtype": "attribute",
-            "name": "target",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 171,
-            "description": "This can be used to query nodes from the target node to be used for \nselection items.  Note this only works if the 'target' property is set.\n\nExample:\n\n    <polymer-selector target=\"{{$.myForm}}\" itemsSelector=\"input[type=radio]\"></polymer-selector>\n    <form id=\"myForm\">\n      <label><input type=\"radio\" name=\"color\" value=\"red\"> Red</label> <br>\n      <label><input type=\"radio\" name=\"color\" value=\"green\"> Green</label> <br>\n      <label><input type=\"radio\" name=\"color\" value=\"blue\"> Blue</label> <br>\n      <p>color = {{color}}</p>\n    </form>",
-            "itemtype": "attribute",
-            "name": "itemSelector",
-            "type": "string",
-            "default": "''",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 190,
-            "description": "The event that would be fired from the item element to indicate\nit is being selected.",
-            "itemtype": "attribute",
-            "name": "activateEvent",
-            "type": "string",
-            "default": "'tap'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        }
-    ],
-    "warnings": []
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/polymer-selector.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/polymer-selector.html
deleted file mode 100644
index a1dcac2..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/polymer-selector.html
+++ /dev/null
@@ -1,371 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
-/**
- * polymer-selector is used to manage a list of elements that can be selected.
- * The attribute "selected" indicates which item element is being selected.
- * The attribute "multi" indicates if multiple items can be selected at once.
- * Tapping on the item element would fire "polymer-activate" event. Use
- * "polymer-select" event to listen for selection changes.
- *
- * Example:
- *
- *     <polymer-selector selected="0">
- *       <div>Item 1</div>
- *       <div>Item 2</div>
- *       <div>Item 3</div>
- *     </polymer-selector>
- *
- * polymer-selector is not styled.  So one needs to use "polymer-selected" CSS
- * class to style the selected element.
- * 
- *     <style>
- *       .item.polymer-selected {
- *         background: #eee;
- *       }
- *     </style>
- *     ...
- *     <polymer-selector>
- *       <div class="item">Item 1</div>
- *       <div class="item">Item 2</div>
- *       <div class="item">Item 3</div>
- *     </polymer-selector>
- *
- * @class polymer-selector
- * @status stable
- */
-/**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- * 
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
-/**
- * Fired when an item element is tapped.
- * 
- * @event polymer-activate
- * @param {Object} detail
- *   @param {Object} detail.item the item element
- */
--->
-<link rel="import" href="../polymer/polymer.html">
-<link rel="import" href="../polymer-selection/polymer-selection.html">
-
-<polymer-element name="polymer-selector"
-    attributes="selected multi valueattr selectedClass selectedProperty selectedAttribute selectedItem selectedModel selectedIndex notap target itemsSelector activateEvent">
-  <template>
-    <polymer-selection id="selection" multi="{{multi}}" on-polymer-select="{{selectionSelect}}"></polymer-selection>
-    <content id="items" select="*"></content>
-  </template>
-  <script>
-    Polymer('polymer-selector', {
-      /**
-       * Gets or sets the selected element.  Default to use the index
-       * of the item element.
-       *
-       * If you want a specific attribute value of the element to be
-       * used instead of index, set "valueattr" to that attribute name.
-       *
-       * Example:
-       *
-       *     <polymer-selector valueattr="label" selected="foo">
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       * In multi-selection this should be an array of values.
-       *
-       * Example:
-       *
-       *     <polymer-selector id="selector" valueattr="label" multi>
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       *     this.$.selector.selected = ['foo', 'zot'];
-       *
-       * @attribute selected
-       * @type Object
-       * @default null
-       */
-      selected: null,
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      /**
-       * Specifies the attribute to be used for "selected" attribute.
-       *
-       * @attribute valueattr
-       * @type string
-       * @default 'name'
-       */
-      valueattr: 'name',
-      /**
-       * Specifies the CSS class to be used to add to the selected element.
-       * 
-       * @attribute selectedClass
-       * @type string
-       * @default 'polymer-selected'
-       */
-      selectedClass: 'polymer-selected',
-      /**
-       * Specifies the property to be used to set on the selected element
-       * to indicate its active state.
-       *
-       * @attribute selectedProperty
-       * @type string
-       * @default ''
-       */
-      selectedProperty: '',
-      /**
-       * Specifies the property to be used to set on the selected element
-       * to indicate its active state.
-       *
-       * @attribute selectedProperty
-       * @type string
-       * @default 'active'
-       */
-      selectedAttribute: 'active',
-      /**
-       * Returns the currently selected element. In multi-selection this returns
-       * an array of selected elements.
-       * 
-       * @attribute selectedItem
-       * @type Object
-       * @default null
-       */
-      selectedItem: null,
-      /**
-       * In single selection, this returns the model associated with the
-       * selected element.
-       * 
-       * @attribute selectedModel
-       * @type Object
-       * @default null
-       */
-      selectedModel: null,
-      /**
-       * In single selection, this returns the selected index.
-       *
-       * @attribute selectedIndex
-       * @type number
-       * @default -1
-       */
-      selectedIndex: -1,
-      /**
-       * The target element that contains items.  If this is not set 
-       * polymer-selector is the container.
-       * 
-       * @attribute target
-       * @type Object
-       * @default null
-       */
-      target: null,
-      /**
-       * This can be used to query nodes from the target node to be used for 
-       * selection items.  Note this only works if the 'target' property is set.
-       *
-       * Example:
-       *
-       *     <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></polymer-selector>
-       *     <form id="myForm">
-       *       <label><input type="radio" name="color" value="red"> Red</label> <br>
-       *       <label><input type="radio" name="color" value="green"> Green</label> <br>
-       *       <label><input type="radio" name="color" value="blue"> Blue</label> <br>
-       *       <p>color = {{color}}</p>
-       *     </form>
-       * 
-       * @attribute itemSelector
-       * @type string
-       * @default ''
-       */
-      itemsSelector: '',
-      /**
-       * The event that would be fired from the item element to indicate
-       * it is being selected.
-       *
-       * @attribute activateEvent
-       * @type string
-       * @default 'tap'
-       */
-      activateEvent: 'tap',
-      notap: false,
-      ready: function() {
-        this.activateListener = this.activateHandler.bind(this);
-        this.observer = new MutationObserver(this.updateSelected.bind(this));
-        if (!this.target) {
-          this.target = this;
-        }
-      },
-      get items() {
-        var nodes = this.target !== this ? (this.itemsSelector ? 
-            this.target.querySelectorAll(this.itemsSelector) : 
-                this.target.children) : this.$.items.getDistributedNodes();
-        return Array.prototype.filter.call(nodes || [], function(n) {
-          return n && n.localName !== 'template';
-        });
-      },
-      targetChanged: function(old) {
-        if (old) {
-          this.removeListener(old);
-          this.observer.disconnect();
-        }
-        if (this.target) {
-          this.addListener(this.target);
-          this.observer.observe(this.target, {childList: true});
-        }
-      },
-      addListener: function(node) {
-        node.addEventListener(this.activateEvent, this.activateListener);
-      },
-      removeListener: function(node) {
-        node.removeEventListener(this.activateEvent, this.activateListener);
-      },
-      get selection() {
-        return this.$.selection.getSelection();
-      },
-      selectedChanged: function() {
-        this.updateSelected();
-      },
-      updateSelected: function() {
-        this.validateSelected();
-        if (this.multi) {
-          this.clearSelection();
-          this.selected && this.selected.forEach(function(s) {
-            this.valueToSelection(s);
-          }, this);
-        } else {
-          this.valueToSelection(this.selected);
-        }
-      },
-      validateSelected: function() {
-        // convert to an array for multi-selection
-        if (this.multi && !Array.isArray(this.selected) && 
-            this.selected !== null && this.selected !== undefined) {
-          this.selected = [this.selected];
-        }
-      },
-      clearSelection: function() {
-        if (this.multi) {
-          this.selection.slice().forEach(function(s) {
-            this.$.selection.setItemSelected(s, false);
-          }, this);
-        } else {
-          this.$.selection.setItemSelected(this.selection, false);
-        }
-        this.selectedItem = null;
-        this.$.selection.clear();
-      },
-      valueToSelection: function(value) {
-        var item = (value === null || value === undefined) ? 
-            null : this.items[this.valueToIndex(value)];
-        this.$.selection.select(item);
-      },
-      updateSelectedItem: function() {
-        this.selectedItem = this.selection;
-      },
-      selectedItemChanged: function() {
-        if (this.selectedItem) {
-          var t = this.selectedItem.templateInstance;
-          this.selectedModel = t ? t.model : undefined;
-        } else {
-          this.selectedModel = null;
-        }
-        this.selectedIndex = this.selectedItem ? 
-            parseInt(this.valueToIndex(this.selected)) : -1;
-      },
-      valueToIndex: function(value) {
-        // find an item with value == value and return it's index
-        for (var i=0, items=this.items, c; (c=items[i]); i++) {
-          if (this.valueForNode(c) == value) {
-            return i;
-          }
-        }
-        // if no item found, the value itself is probably the index
-        return value;
-      },
-      valueForNode: function(node) {
-        return node[this.valueattr] || node.getAttribute(this.valueattr);
-      },
-      // events fired from <polymer-selection> object
-      selectionSelect: function(e, detail) {
-        this.updateSelectedItem();
-        if (detail.item) {
-          this.applySelection(detail.item, detail.isSelected);
-        }
-      },
-      applySelection: function(item, isSelected) {
-        if (this.selectedClass) {
-          item.classList.toggle(this.selectedClass, isSelected);
-        }
-        if (this.selectedProperty) {
-          item[this.selectedProperty] = isSelected;
-        }
-        if (this.selectedAttribute && item.setAttribute) {
-          if (isSelected) {
-            item.setAttribute(this.selectedAttribute, '');
-          } else {
-            item.removeAttribute(this.selectedAttribute);
-          }
-        }
-      },
-      // event fired from host
-      activateHandler: function(e) {
-        if (!this.notap) {
-          var i = this.findDistributedTarget(e.target, this.items);
-          if (i >= 0) {
-            var item = this.items[i];
-            var s = this.valueForNode(item) || i;
-            if (this.multi) {
-              if (this.selected) {
-                this.addRemoveSelected(s);
-              } else {
-                this.selected = [s];
-              }
-            } else {
-              this.selected = s;
-            }
-            this.asyncFire('polymer-activate', {item: item});
-          }
-        }
-      },
-      addRemoveSelected: function(value) {
-        var i = this.selected.indexOf(value);
-        if (i >= 0) {
-          this.selected.splice(i, 1);
-        } else {
-          this.selected.push(value);
-        }
-        this.valueToSelection(value);
-      },
-      findDistributedTarget: function(target, nodes) {
-        // find first ancestor of target (including itself) that
-        // is in nodes, if any
-        while (target && target != this) {
-          var i = Array.prototype.indexOf.call(nodes, target);
-          if (i >= 0) {
-            return i;
-          }
-          target = target.parentNode;
-        }
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-activate-event.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-activate-event.html
deleted file mode 100644
index a552a68..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-activate-event.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selector-activate-event</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selector.html">
-  <style>
-    .polymer-selected {
-      background: #ccc;
-    }
-  </style>
-</head>
-<body>
-
-  <polymer-selector id="selector" selected="0">
-    <div>Item 1</div>
-    <div>Item 2</div>
-    <div>Item 3</div>
-    <div>Item 4</div>
-    <div>Item 5</div>
-  </polymer-selector>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('#selector');
-      s.addEventListener("polymer-activate", function(event) {
-        assert.equal(event.detail.item, s.children[1]);
-        assert.equal(s.selected, 1);
-        done();
-      });
-      assert.equal(s.selected, '0');
-      requestAnimationFrame(function() {
-        s.children[1].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
-      });
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-basic.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-basic.html
deleted file mode 100644
index 37d57eb..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-basic.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selector-basic</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selector.html">
-  <style>
-    .polymer-selected {
-      background: #ccc;
-    }
-    
-    .my-selected {
-      background: red;
-    }
-  </style>
-</head>
-<body>
-
-  <polymer-selector id="selector1">
-    <div>Item 1</div>
-    <div>Item 2</div>
-    <div>Item 3</div>
-    <div>Item 4</div>
-    <div>Item 5</div>
-  </polymer-selector>
-  
-  <br><br>
-  
-  <polymer-selector id="selector2" selected="item3" selectedClass="my-selected" valueattr="id">
-    <div id="item1">Item 1</div>
-    <div id="item2">Item 2</div>
-    <div id="item3">Item 3</div>
-    <div id="item4">Item 4</div>
-    <div id="item5">Item 5</div>
-  </polymer-selector>
-  
-  <script>
-    var assert = chai.assert;
-    var async = requestAnimationFrame;
-    
-    function oneMutation(node, options, cb) {
-      var o = new MutationObserver(function() {
-        cb();
-        o.disconnect();
-      });
-      o.observe(node, options);
-    }
-    
-    document.addEventListener('polymer-ready', function() {
-      // selector1
-      var s = document.querySelector('#selector1');
-      assert.equal(s.selected, null);
-      assert.equal(s.selectedClass, 'polymer-selected');
-      assert.isFalse(s.multi);
-      assert.equal(s.valueattr, 'name');
-      assert.equal(s.items.length, 5);
-      // selector2
-      s = document.querySelector('#selector2');
-      assert.equal(s.selected, "item3");
-      assert.equal(s.selectedClass, 'my-selected');
-      // setup listener for polymer-select event
-      var selectEventCounter = 0;
-      s.addEventListener('polymer-select', function(e) {
-        if (e.detail.isSelected) {
-          selectEventCounter++;
-          // selectedItem and detail.item should be the same
-          assert.equal(e.detail.item, s.selectedItem);
-        }
-      });
-      // set selected
-      s.selected = 'item5';
-      Platform.flush();
-      oneMutation(s, {attributes: true}, function() {
-        // check polymer-select event
-        assert.equal(selectEventCounter, 1);
-        // check selected class
-        assert.isTrue(s.children[4].classList.contains('my-selected'));
-        // check selectedItem
-        assert.equal(s.selectedItem, s.children[4]);
-        // selecting the same value shouldn't fire polymer-select
-        selectEventCounter = 0;
-        s.selected = 'item5';
-        Platform.flush();
-        // TODO(ffu): would be better to wait for something to happen
-        // instead of not to happen
-        setTimeout(function() {
-          assert.equal(selectEventCounter, 0);
-          done();
-        }, 50);
-      });
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-multi.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-multi.html
deleted file mode 100644
index 755e7fd..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-multi.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selector-multi</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selector.html">
-  <style>
-    .polymer-selected {
-      background: #ccc;
-    }
-  </style>
-</head>
-<body>
-
-  <polymer-selector id="selector" multi>
-    <div>Item 1</div>
-    <div>Item 2</div>
-    <div>Item 3</div>
-    <div>Item 4</div>
-    <div>Item 5</div>
-  </polymer-selector>
-  
-  <script>
-    var assert = chai.assert;
-    
-    function oneMutation(node, options, cb) {
-      var o = new MutationObserver(function() {
-        cb();
-        o.disconnect();
-      });
-      o.observe(node, options);
-    }
-    
-    document.addEventListener('polymer-ready', function() {
-      //
-      var s = document.querySelector('#selector');
-      assert.equal(s.selected, null);
-      assert.equal(s.selectedClass, 'polymer-selected');
-      assert.isTrue(s.multi);
-      assert.equal(s.valueattr, 'name');
-      assert.equal(s.items.length, 5);
-      // setup listener for polymer-select event
-      var selectEventCounter = 0;
-      s.addEventListener('polymer-select', function(e) {
-        if (e.detail.isSelected) {
-          selectEventCounter++;
-        } else {
-          selectEventCounter--;
-        }
-        // check selectedItem in polymer-select event
-        assert.equal(this.selectedItem.length, selectEventCounter);
-      });
-      // set selected
-      s.selected = [0, 2];
-      Platform.flush();
-      oneMutation(s, {attributes: true}, function() {
-        // check polymer-select event
-        assert.equal(selectEventCounter, 2);
-        // check selected class
-        assert.isTrue(s.children[0].classList.contains('polymer-selected'));
-        assert.isTrue(s.children[2].classList.contains('polymer-selected'));
-        // check selectedItem
-        assert.equal(s.selectedItem.length, 2);
-        assert.equal(s.selectedItem[0], s.children[0]);
-        assert.equal(s.selectedItem[1], s.children[2]);
-        // tap on already selected element should unselect it
-        s.children[0].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
-        // check selected
-        assert.equal(s.selected.length, 1);
-        assert.isFalse(s.children[0].classList.contains('polymer-selected'));
-        done();
-      });
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/js/polymer-selector.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/js/polymer-selector.js
deleted file mode 100644
index 537fa39..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/js/polymer-selector.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*

- * Copyright 2013 The Polymer Authors. All rights reserved.

- * Use of this source code is governed by a BSD-style

- * license that can be found in the LICENSE file.

- */

-

-htmlSuite('polymer-selector', function() {

-  htmlTest('html/polymer-selector-basic.html');

-  htmlTest('html/polymer-selector-activate-event.html');

-  htmlTest('html/polymer-selector-multi.html');

-});
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/runner.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/runner.html
deleted file mode 100644
index 378815f..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/runner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>polymer-selector Test Runner (Mocha)</title>
-    <meta charset="UTF-8">
-    <!-- -->
-    <link rel="stylesheet" href="../../tools/test/mocha/mocha.css" />
-    <script src="../../tools/test/mocha/mocha.js"></script>
-    <script src="../../tools/test/chai/chai.js"></script>
-    <script src="../../tools/test/mocha-htmltest.js"></script>
-    <!-- -->
-    <script src="../../platform/platform.js"></script>
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script>
-      mocha.setup({ui: 'tdd', slow: 1000, htmlbase: ''});
-    </script>
-    <!-- -->
-    <script src="js/polymer-selector.js"></script>
-    <!-- -->
-    <script>
-      mocha.run();
-    </script>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/.bower.json
deleted file mode 100644
index 86c1530..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/.bower.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  "name": "polymer",
-  "description": "Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.",
-  "homepage": "http://www.polymer-project.org/",
-  "keywords": [
-    "util",
-    "client",
-    "browser",
-    "web components",
-    "web-components"
-  ],
-  "author": "Polymer Authors <polymer-dev@googlegroups.com>",
-  "main": [
-    "polymer.js"
-  ],
-  "dependencies": {
-    "platform": "Polymer/platform#0.2.1"
-  },
-  "version": "0.2.1",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "62ec4216813ccd9344cf419da846b623892f0884"
-  },
-  "_source": "git://github.com/Polymer/polymer.git",
-  "_target": "0.2.1",
-  "_originalSource": "Polymer/polymer"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/CONTRIBUTING.md
deleted file mode 100644
index 1de2f34..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/CONTRIBUTING.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Contributing
-
-Want to contribute to Polymer? Great!
-
-We are more than happy to accept external contributions to the project in the form of [feedback](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev), [bug reports](../../issues), and pull requests.
-
-## Contributor License Agreement
-
-Before we can accept patches, there's a quick web form you need to fill out.
-
-- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
-- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
-
-This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
-
-Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
-
-[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
-
-## Initial setup
-
-Here's an easy guide that should get you up and running:
-
-1. Setup Grunt: `sudo npm install -g grunt-cli`
-1. Fork the project on github and pull down your copy.
-   > replace the {{ username }} with your username and {{ repository }} with the repository name
-
-        git clone git@github.com:{{ username }}/{{ repository }}.git --recursive
-
-    Note the `--recursive`. This is necessary for submodules to initialize properly. If you don't do a recursive clone, you'll have to init them manually:
-
-        git submodule init
-        git submodule update
-
-    Download and run the `pull-all.sh` script to install the sibling dependencies.
-
-        git clone git://github.com/Polymer/tools.git && tools/bin/pull-all.sh
-
-1. Test your change
-   > in the repo you've made changes to, run the tests:
-
-        cd $REPO
-        npm install
-        grunt test
-
-1. Commit your code and make a pull request.
-
-That's it for the one time setup. Now you're ready to make a change.
-
-## Submitting a pull request
-
-We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
-
-    git remote add upstream git://github.com/Polymer/{{ repository }}.git
-
-Then before making a change, do a pull from the upstream `master` branch:
-
-    git pull upstream master
-
-To make life easier, add a "pull upstream" alias in your `.gitconfig`:
-
-    [alias]
-      pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
-
-That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
-
-    git checkout master
-    git pu
-    # make change
-    git commit -a -m 'Awesome things.'
-    git push
-
-Lastly, don't forget to submit the pull request.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/LICENSE
deleted file mode 100644
index 95987ba..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2014 The Polymer 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/samples/third_party/todomvc_performance/js_todomvc/components/polymer/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/README.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/README.md
deleted file mode 100644
index 236a88c..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Polymer
-
-[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/polymer/README)](https://github.com/igrigorik/ga-beacon)
-
-Build Status: [http://build.chromium.org/p/client.polymer/waterfall](http://build.chromium.org/p/client.polymer/waterfall)
-
-## Brief Overview
-
-For more detailed info goto [http://polymer-project.org/](http://polymer-project.org/).
-
-Polymer is a new type of library for the web, designed to leverage the existing browser infrastructure to provide the encapsulation and extendability currently only available in JS libraries.
-
-Polymer is based on a set of future technologies, including [Shadow DOM](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html), [Custom Elements](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html) and Model Driven Views. Currently these technologies are implemented as polyfills or shims, but as browsers adopt these features natively, the platform code that drives Polymer evacipates, leaving only the value-adds.
-
-## Tools & Testing
-
-For running tests or building minified files, consult the [tooling information](http://www.polymer-project.org/resources/tooling-strategy.html).
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/bower.json
deleted file mode 100644
index bd7a8ea..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/bower.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "polymer",
-  "description": "Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.",
-  "homepage": "http://www.polymer-project.org/",
-  "keywords": [
-    "util",
-    "client",
-    "browser",
-    "web components",
-    "web-components"
-  ],
-  "author": "Polymer Authors <polymer-dev@googlegroups.com>",
-  "main": [
-    "polymer.js"
-  ],
-  "dependencies": {
-    "platform": "Polymer/platform#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer-body.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer-body.html
deleted file mode 100644
index 5f07a01..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer-body.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<polymer-element name="polymer-body" extends="body">
-
-  <script>
-
-  // upgrade polymer-body last so that it can contain other imported elements
-  document.addEventListener('polymer-ready', function() {
-    
-    Polymer('polymer-body', Platform.mixin({
-
-      created: function() {
-        this.template = document.createElement('template');
-        var body = wrap(document).body;
-        var c$ = body.childNodes.array();
-        for (var i=0, c; (c=c$[i]); i++) {
-          if (c.localName !== 'script') {
-            this.template.content.appendChild(c);
-          }
-        }
-        // snarf up user defined model
-        window.model = this;
-      },
-
-      parseDeclaration: function(elementElement) {
-        this.lightFromTemplate(this.template);
-      }
-
-    }, window.model));
-
-  });
-
-  </script>
-
-</polymer-element>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.html
deleted file mode 100644
index ae23866..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!--
- Copyright 2013 The Polymer Authors. All rights reserved.
- Use of this source code is governed by a BSD-style
- license that can be found in the LICENSE file.
--->
-<script src="polymer.js"></script>
-<!-- <link rel="import" href="../polymer-dev/polymer.html"> -->
-<link rel="import" href="polymer-body.html">
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js
deleted file mode 100644
index f4d249f..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @license
- * Copyright (c) 2012-2014 The Polymer 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.
- */
-// @version: 0.2.1
-Polymer={},"function"==typeof window.Polymer&&(Polymer={}),function(a){function b(a,b){return a&&b&&Object.getOwnPropertyNames(b).forEach(function(c){var d=Object.getOwnPropertyDescriptor(b,c);d&&(Object.defineProperty(a,c,d),"function"==typeof d.value&&(d.value.nom=c))}),a}a.extend=b}(Polymer),function(a){function b(a,b,d){return a?a.stop():a=new c(this),a.go(b,d),a}var c=function(a){this.context=a,this.boundComplete=this.complete.bind(this)};c.prototype={go:function(a,b){this.callback=a;var c;b?(c=setTimeout(this.boundComplete,b),this.handle=function(){clearTimeout(c)}):(c=requestAnimationFrame(this.boundComplete),this.handle=function(){cancelAnimationFrame(c)})},stop:function(){this.handle&&(this.handle(),this.handle=null)},complete:function(){this.handle&&(this.stop(),this.callback.call(this.context))}},a.job=b}(Polymer),function(){var a={};HTMLElement.register=function(b,c){a[b]=c},HTMLElement.getPrototypeForTag=function(b){var c=b?a[b]:HTMLElement.prototype;return c||Object.getPrototypeOf(document.createElement(b))};var b=Event.prototype.stopPropagation;Event.prototype.stopPropagation=function(){this.cancelBubble=!0,b.apply(this,arguments)}}(Polymer),function(a){function b(a){var c=b.caller,g=c.nom,h=c._super;if(h||(g||(g=c.nom=e.call(this,c)),g||console.warn("called super() on a method not installed declaratively (has no .nom property)"),h=d(c,g,f(this))),h){var i=h[g];return i._super||d(i,g,h),i.apply(this,a||[])}}function c(a,b,c){for(;a;){if(a[b]!==c&&a[b])return a;a=f(a)}}function d(a,b,d){return a._super=c(d,b,a),a._super&&(a._super[b].nom=b),a._super}function e(a){for(var b=this.__proto__;b&&b!==HTMLElement.prototype;){for(var c,d=Object.getOwnPropertyNames(b),e=0,f=d.length;f>e&&(c=d[e]);e++){var g=Object.getOwnPropertyDescriptor(b,c);if("function"==typeof g.value&&g.value===a)return c}b=b.__proto__}}function f(a){return a.__proto__}a.super=b}(Polymer),function(a){function b(a,b){var d=typeof b;return b instanceof Date&&(d="date"),c[d](a,b)}var c={string:function(a){return a},date:function(a){return new Date(Date.parse(a)||Date.now())},"boolean":function(a){return""===a?!0:"false"===a?!1:!!a},number:function(a){var b=parseFloat(a);return 0===b&&(b=parseInt(a)),isNaN(b)?a:b},object:function(a,b){if(null===b)return a;try{return JSON.parse(a.replace(/'/g,'"'))}catch(c){return a}},"function":function(a,b){return b}};a.deserializeValue=b}(Polymer),function(a){var b=a.extend,c={};c.declaration={},c.instance={},c.publish=function(a,c){for(var d in a)b(c,a[d])},a.api=c}(Polymer),function(a){var b={async:function(a,b,c){Platform.flush(),b=b&&b.length?b:[b];var d=function(){(this[a]||a).apply(this,b)}.bind(this),e=c?setTimeout(d,c):requestAnimationFrame(d);return c?e:1/e},cancelAsync:function(a){1>a?cancelAnimationFrame(Math.round(1/a)):clearTimeout(a)},fire:function(a,b,c,d,e){var f=c||this,b=b||{},g=new CustomEvent(a,{bubbles:void 0!==d?d:!0,cancelable:void 0!==e?e:!0,detail:b});return f.dispatchEvent(g),g},asyncFire:function(){this.async("fire",arguments)},classFollows:function(a,b,c){b&&b.classList.remove(c),a&&a.classList.add(c)}},c=function(){},d={};b.asyncMethod=b.async,a.api.instance.utils=b,a.nop=c,a.nob=d}(Polymer),function(a){var b=window.logFlags||{},c="on-",d={EVENT_PREFIX:c,addHostListeners:function(){var a=this.eventDelegates;b.events&&Object.keys(a).length>0&&console.log("[%s] addHostListeners:",this.localName,a);var d,e,f=this;for(var g in a)e=c+g,(d=PolymerExpressions.prepareEventBinding(Path.get(a[g]),e,{resolveEventHandler:function(a,b){var c=b.getValueFrom(f);return c?c.bind(f):void 0}}))(this,this,!1)},dispatchMethod:function(a,c,d){if(a){b.events&&console.group("[%s] dispatch [%s]",a.localName,c);var e="function"==typeof c?c:a[c];e&&e[d?"apply":"call"](a,d),b.events&&console.groupEnd(),Platform.flush()}}};a.api.instance.events=d}(Polymer),function(a){var b={copyInstanceAttributes:function(){var a=this._instanceAttributes;for(var b in a)this.hasAttribute(b)||this.setAttribute(b,a[b])},takeAttributes:function(){if(this._publishLC)for(var a,b=0,c=this.attributes,d=c.length;(a=c[b])&&d>b;b++)this.attributeToProperty(a.name,a.value)},attributeToProperty:function(b,c){var b=this.propertyForAttribute(b);if(b){if(c&&c.search(a.bindPattern)>=0)return;var d=this[b],c=this.deserializeValue(c,d);c!==d&&(this[b]=c)}},propertyForAttribute:function(a){var b=this._publishLC&&this._publishLC[a];return b},deserializeValue:function(b,c){return a.deserializeValue(b,c)},serializeValue:function(a,b){return"boolean"===b?a?"":void 0:"object"!==b&&"function"!==b&&void 0!==a?a:void 0},reflectPropertyToAttribute:function(a){var b=typeof this[a],c=this.serializeValue(this[a],b);void 0!==c?this.setAttribute(a,c):"boolean"===b&&this.removeAttribute(a)}};a.api.instance.attributes=b}(Polymer),function(a){function b(a,b,d){c.bind&&console.log(e,inB.localName||"object",inPath,a.localName,b);var f=d.discardChanges();return(null===f||void 0===f)&&d.setValue(a[b]),Observer.defineComputedProperty(a,b,d)}var c=window.logFlags||{},d={observeProperties:function(){var a=this._observeNames,b=this._publishNames;if(a&&a.length||b&&b.length){for(var c,d=this._propertyObserver=new CompoundObserver,e=0,f=a.length;f>e&&(c=a[e]);e++){d.addPath(this,c);var g=Object.getOwnPropertyDescriptor(this.__proto__,c);g&&g.value&&this.observeArrayValue(c,g.value,null)}for(var c,e=0,f=b.length;f>e&&(c=b[e]);e++)this.observe&&void 0!==this.observe[c]||d.addPath(this,c);d.open(this.notifyPropertyChanges,this)}},notifyPropertyChanges:function(a,b,c){var d,e,f={};for(var g in b)d=c[2*g+1],void 0!==this.publish[d]&&this.reflectPropertyToAttribute(d),e=this.observe[d],e&&(this.observeArrayValue(d,a[g],b[g]),f[e]||(f[e]=!0,this.invokeMethod(e,[b[g],a[g],arguments])))},observeArrayValue:function(a,b,d){var e=this.observe[a];if(e&&(Array.isArray(d)&&(c.observe&&console.log("[%s] observeArrayValue: unregister observer [%s]",this.localName,a),this.unregisterObserver(a+"__array")),Array.isArray(b))){c.observe&&console.log("[%s] observeArrayValue: register observer [%s]",this.localName,a,b);var f=new ArrayObserver(b);f.open(function(a,b){this.invokeMethod(e,[b])},this),this.registerObserver(a+"__array",f)}},bindProperty:function(a,c){return b(this,a,c)},unbindAllProperties:function(){this._propertyObserver&&this._propertyObserver.close(),this.unregisterObservers()},unbindProperty:function(a){return this.unregisterObserver(a)},invokeMethod:function(a,b){var c=this[a]||a;"function"==typeof c&&c.apply(this,b)},registerObserver:function(a,b){var c=this._observers||(this._observers={});c[a]=b},unregisterObserver:function(a){var b=this._observers;return b&&b[a]?(b[a].close(),b[a]=null,!0):void 0},unregisterObservers:function(){if(this._observers){for(var a,b,c=Object.keys(this._observers),d=0,e=c.length;e>d&&(a=c[d]);d++)b=this._observers[a],b.close();this._observers={}}}},e="[%s]: bindProperties: [%s] to [%s].[%s]";a.api.instance.properties=d}(Polymer),function(a){function b(a){for(;a.parentNode;){if(a.lightDomController)return a;a=a.parentNode}return a.host}function c(a){e(a,d)}function d(a){a.unbindAll()}function e(a,b){if(a){b(a);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}}var f=window.logFlags||0,g=(a.api.instance.events,new PolymerExpressions);g.resolveEventHandler=function(a,c,d){var e=b(d);if(e){var f=c.getValueFrom(e);if(f)return f.bind(e)}};var h={syntax:g,instanceTemplate:function(a){return a.createInstance(this,this.syntax)},bind:function(a,b){this._elementPrepared||this.prepareElement();var c=this.propertyForAttribute(a);if(c){this.unbind(a);var d=this.bindProperty(c,b);return d.path=b.path_,this.reflectPropertyToAttribute(c),this.bindings[a]=d}return this.mixinSuper(arguments)},asyncUnbindAll:function(){this._unbound||(f.unbind&&console.log("[%s] asyncUnbindAll",this.localName),this._unbindAllJob=this.job(this._unbindAllJob,this.unbindAll,0))},unbindAll:function(){if(!this._unbound){this.unbindAllProperties(),this.super();for(var a=this.shadowRoot;a;)c(a),a=a.olderShadowRoot;this._unbound=!0}},cancelUnbindAll:function(a){return this._unbound?void(f.unbind&&console.warn("[%s] already unbound, cannot cancel unbindAll",this.localName)):(f.unbind&&console.log("[%s] cancelUnbindAll",this.localName),this._unbindAllJob&&(this._unbindAllJob=this._unbindAllJob.stop()),void(a||e(this.shadowRoot,function(a){a.cancelUnbindAll&&a.cancelUnbindAll()})))}},i=/\{\{([^{}]*)}}/;a.bindPattern=i,a.api.instance.mdv=h}(Polymer),function(a){function b(a){return a.hasOwnProperty("PolymerBase")}function c(){}var d=0,e={PolymerBase:!0,job:Polymer.job,"super":Polymer.super,created:function(){},ready:function(){},createdCallback:function(){this.created(),(this.ownerDocument.defaultView||this.alwaysPrepare||d>0)&&this.prepareElement()},prepareElement:function(){this._elementPrepared=!0,this.shadowRoots={},this.observeProperties(),this.copyInstanceAttributes(),this.takeAttributes(),this.addHostListeners(),d++,this.parseDeclarations(this.__proto__),d--,this.removeAttribute("unresolved"),this.ready()},attachedCallback:function(){this._elementPrepared||this.prepareElement(),this.cancelUnbindAll(!0),this.attached&&this.attached(),this.enteredView&&this.enteredView(),this.hasBeenAttached||(this.hasBeenAttached=!0,this.domReady&&this.async("domReady"))},detachedCallback:function(){this.preventDispose||this.asyncUnbindAll(),this.detached&&this.detached(),this.leftView&&this.leftView()},enteredViewCallback:function(){this.attachedCallback()},leftViewCallback:function(){this.detachedCallback()},enteredDocumentCallback:function(){this.attachedCallback()},leftDocumentCallback:function(){this.detachedCallback()},parseDeclarations:function(a){a&&a.element&&(this.parseDeclarations(a.__proto__),a.parseDeclaration.call(this,a.element))},parseDeclaration:function(a){var b=this.fetchTemplate(a);if(b){var c=this.shadowFromTemplate(b);this.shadowRoots[a.name]=c}},fetchTemplate:function(a){return a.querySelector("template")},shadowFromTemplate:function(a){if(a){var b=this.createShadowRoot();b.resetStyleInheritance=this.resetStyleInheritance;var c=this.instanceTemplate(a);return b.appendChild(c),this.shadowRootReady(b,a),b}},lightFromTemplate:function(a){if(a){this.lightDomController=!0;var b=this.instanceTemplate(a);return this.appendChild(b),this.shadowRootReady(this,a),b}},shadowRootReady:function(a){this.marshalNodeReferences(a),PointerGestures.register(a)},marshalNodeReferences:function(a){var b=this.$=this.$||{};if(a)for(var c,d=a.querySelectorAll("[id]"),e=0,f=d.length;f>e&&(c=d[e]);e++)b[c.id]=c},attributeChangedCallback:function(a){"class"!==a&&"style"!==a&&this.attributeToProperty(a,this.getAttribute(a)),this.attributeChanged&&this.attributeChanged.apply(this,arguments)},onMutation:function(a,b){var c=new MutationObserver(function(a){b.call(this,c,a),c.disconnect()}.bind(this));c.observe(a,{childList:!0,subtree:!0})}};c.prototype=e,e.constructor=c,a.Base=c,a.isBase=b,a.api.instance.base=e}(Polymer),function(a){function b(a){return a.__proto__}function c(a,b){var c="",d=!1;b&&(c=b.localName,d=b.hasAttribute("is"));var e=Platform.ShadowCSS.makeScopeSelector(c,d);return Platform.ShadowCSS.shimCssText(a,e)}var d=(window.logFlags||{},"element"),e="controller",f={STYLE_SCOPE_ATTRIBUTE:d,installControllerStyles:function(){var a=this.findStyleScope();if(a&&!this.scopeHasNamedStyle(a,this.localName)){for(var c=b(this),d="";c&&c.element;)d+=c.element.cssTextForScope(e),c=b(c);d&&this.installScopeCssText(d,a)}},installScopeStyle:function(a,b){var c=this.findStyleScope(),b=b||"";if(c&&!this.scopeHasNamedStyle(c,this.localName+b)){var d="";if(a instanceof Array)for(var e,f=0,g=a.length;g>f&&(e=a[f]);f++)d+=e.textContent+"\n\n";else d=a.textContent;this.installScopeCssText(d,c,b)}},installScopeCssText:function(a,b,d){if(b=b||this.findStyleScope(),d=d||"",b){window.ShadowDOMPolyfill&&(a=c(a,b.host));var f=this.element.cssTextToScopeStyle(a,e);Polymer.applyStyleToScope(f,b),b._scopeStyles[this.localName+d]=!0}},findStyleScope:function(){for(var a=this;a.parentNode;)a=a.parentNode;return a},scopeHasNamedStyle:function(a,b){return a._scopeStyles=a._scopeStyles||{},a._scopeStyles[b]}};a.api.instance.styles=f}(Polymer),function(a){function b(a,b){if(f[a])throw"Already registered (Polymer) prototype for element "+a;e(a,b),d(a)}function c(a,b){h[a]=b}function d(a){h[a]&&(h[a].registerWhenReady(),delete h[a])}function e(a,b){return i[a]=b||{}}function f(a){return i[a]}var g=a.extend,h=(a.api,{}),i={};a.getRegisteredPrototype=f,a.waitingForPrototype=c,window.Polymer=b,g(Polymer,a);var j=Platform.deliverDeclarations();if(j)for(var k,l=0,m=j.length;m>l&&(k=j[l]);l++)b.apply(null,k)}(Polymer),function(a){var b={resolveElementPaths:function(a){Platform.urlResolver.resolveDom(a)},addResolvePathApi:function(){var a=this.getAttribute("assetpath")||"",b=new URL(a,this.ownerDocument.baseURI);this.prototype.resolvePath=function(a,c){var d=new URL(a,c||b);return d.href}}};a.api.declaration.path=b}(Polymer),function(a){function b(a,b){var c=new URL(a.getAttribute("href"),b).href;return"@import '"+c+"';"}function c(a,b){if(a){b===document&&(b=document.head),window.ShadowDOMPolyfill&&(b=document.head);var c=d(a.textContent),e=a.getAttribute(h);e&&c.setAttribute(h,e),b.appendChild(c)}}function d(a,b){b=b||document,b=b.createElement?b:b.ownerDocument;var c=b.createElement("style");return c.textContent=a,c}function e(a){return a&&a.__resource||""}function f(a,b){return p?p.call(a,b):void 0}var g=(window.logFlags||{},a.api.instance.styles),h=g.STYLE_SCOPE_ATTRIBUTE,i="style",j="@import",k="link[rel=stylesheet]",l="global",m="polymer-scope",n={loadStyles:function(a){var b=this.templateContent();b&&this.convertSheetsToStyles(b);var c=this.findLoadableStyles(b);c.length?Platform.styleResolver.loadStyles(c,a):a&&a()},convertSheetsToStyles:function(a){for(var c,e,f=a.querySelectorAll(k),g=0,h=f.length;h>g&&(c=f[g]);g++)e=d(b(c,this.ownerDocument.baseURI),this.ownerDocument),this.copySheetAttributes(e,c),c.parentNode.replaceChild(e,c)},copySheetAttributes:function(a,b){for(var c,d=0,e=b.attributes,f=e.length;(c=e[d])&&f>d;d++)"rel"!==c.name&&"href"!==c.name&&a.setAttribute(c.name,c.value)},findLoadableStyles:function(a){var b=[];if(a)for(var c,d=a.querySelectorAll(i),e=0,f=d.length;f>e&&(c=d[e]);e++)c.textContent.match(j)&&b.push(c);return b},installSheets:function(){this.cacheSheets(),this.cacheStyles(),this.installLocalSheets(),this.installGlobalStyles()},cacheSheets:function(){this.sheets=this.findNodes(k),this.sheets.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},cacheStyles:function(){this.styles=this.findNodes(i+"["+m+"]"),this.styles.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},installLocalSheets:function(){var a=this.sheets.filter(function(a){return!a.hasAttribute(m)}),b=this.templateContent();if(b){var c="";if(a.forEach(function(a){c+=e(a)+"\n"}),c){var f=d(c,this.ownerDocument);b.insertBefore(f,b.firstChild)}}},findNodes:function(a,b){var c=this.querySelectorAll(a).array(),d=this.templateContent();if(d){var e=d.querySelectorAll(a).array();c=c.concat(e)}return b?c.filter(b):c},templateContent:function(){var a=this.querySelector("template");return a&&templateContent(a)},installGlobalStyles:function(){var a=this.styleForScope(l);c(a,document.head)},cssTextForScope:function(a){var b="",c="["+m+"="+a+"]",d=function(a){return f(a,c)},g=this.sheets.filter(d);g.forEach(function(a){b+=e(a)+"\n\n"});var h=this.styles.filter(d);return h.forEach(function(a){b+=a.textContent+"\n\n"}),b},styleForScope:function(a){var b=this.cssTextForScope(a);return this.cssTextToScopeStyle(b,a)},cssTextToScopeStyle:function(a,b){if(a){var c=d(a);return c.setAttribute(h,this.getAttribute("name")+"-"+b),c}}},o=HTMLElement.prototype,p=o.matches||o.matchesSelector||o.webkitMatchesSelector||o.mozMatchesSelector;a.api.declaration.styles=n,a.applyStyleToScope=c}(Polymer),function(a){var b=(window.logFlags||{},a.api.instance.events),c=b.EVENT_PREFIX,d={parseHostEvents:function(){var a=this.prototype.eventDelegates;this.addAttributeDelegates(a)},addAttributeDelegates:function(a){for(var b,c=0;b=this.attributes[c];c++)this.hasEventPrefix(b.name)&&(a[this.removeEventPrefix(b.name)]=b.value.replace("{{","").replace("}}","").trim())},hasEventPrefix:function(a){return a&&"o"===a[0]&&"n"===a[1]&&"-"===a[2]},removeEventPrefix:function(a){return a.slice(e)}},e=c.length;a.api.declaration.events=d}(Polymer),function(a){var b={inferObservers:function(a){var b,c=a.observe;for(var d in a)"Changed"===d.slice(-7)&&(c||(c=a.observe={}),b=d.slice(0,-7),c[b]=c[b]||d)},explodeObservers:function(a){var b=a.observe;if(b){var c={};for(var d in b)for(var e,f=d.split(" "),g=0;e=f[g];g++)c[e]=b[d];a.observe=c}},optimizePropertyMaps:function(a){if(a.observe){var b=a._observeNames=[];for(var c in a.observe)for(var d,e=c.split(" "),f=0;d=e[f];f++)b.push(d)}if(a.publish){var b=a._publishNames=[];for(var c in a.publish)b.push(c)}},publishProperties:function(a,b){var c=a.publish;c&&(this.requireProperties(c,a,b),a._publishLC=this.lowerCaseMap(c))},requireProperties:function(a,b,c){for(var d in a)void 0===b[d]&&void 0===c[d]&&(b[d]=a[d])},lowerCaseMap:function(a){var b={};for(var c in a)b[c.toLowerCase()]=c;return b}};a.api.declaration.properties=b}(Polymer),function(a){var b="attributes",c=/\s|,/,d={inheritAttributesObjects:function(a){this.inheritObject(a,"publishLC"),this.inheritObject(a,"_instanceAttributes")},publishAttributes:function(a,d){var e=this.getAttribute(b);if(e)for(var f,g=a.publish||(a.publish={}),h=e.split(c),i=0,j=h.length;j>i;i++)f=h[i].trim(),f&&void 0===g[f]&&void 0===d[f]&&(g[f]=null)},accumulateInstanceAttributes:function(){for(var a,b=this.prototype._instanceAttributes,c=this.attributes,d=0,e=c.length;e>d&&(a=c[d]);d++)this.isInstanceAttribute(a.name)&&(b[a.name]=a.value)},isInstanceAttribute:function(a){return!this.blackList[a]&&"on-"!==a.slice(0,3)},blackList:{name:1,"extends":1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1}};d.blackList[b]=1,a.api.declaration.attributes=d}(Polymer),function(a){function b(a){if(!Object.__proto__){var b=Object.getPrototypeOf(a);a.__proto__=b,d(b)&&(b.__proto__=Object.getPrototypeOf(b))}}var c=a.api,d=a.isBase,e=a.extend,f={register:function(a,b){this.buildPrototype(a,b),this.registerPrototype(a,b),this.publishConstructor()},buildPrototype:function(b,c){var d=a.getRegisteredPrototype(b),e=this.generateBasePrototype(c);this.desugarBeforeChaining(d,e),this.prototype=this.chainPrototypes(d,e),this.desugarAfterChaining(b,c)},desugarBeforeChaining:function(a,b){a.element=this,this.publishAttributes(a,b),this.publishProperties(a,b),this.inferObservers(a),this.explodeObservers(a)},chainPrototypes:function(a,c){this.inheritMetaData(a,c);var d=this.chainObject(a,c);return b(d),d},inheritMetaData:function(a,b){this.inheritObject("observe",a,b),this.inheritObject("publish",a,b),this.inheritObject("_publishLC",a,b),this.inheritObject("_instanceAttributes",a,b),this.inheritObject("eventDelegates",a,b)},desugarAfterChaining:function(a,b){this.optimizePropertyMaps(this.prototype),this.installSheets(),this.resolveElementPaths(this),this.accumulateInstanceAttributes(),this.parseHostEvents(),this.addResolvePathApi(),window.ShadowDOMPolyfill&&Platform.ShadowCSS.shimStyling(this.templateContent(),a,b),this.prototype.registerCallback&&this.prototype.registerCallback(this)},publishConstructor:function(){var a=this.getAttribute("constructor");a&&(window[a]=this.ctor)},generateBasePrototype:function(a){var b=this.findBasePrototype(a);if(!b){var b=HTMLElement.getPrototypeForTag(a);b=this.ensureBaseApi(b),g[a]=b}return b},findBasePrototype:function(a){return g[a]},ensureBaseApi:function(a){if(a.PolymerBase)return a;var b=Object.create(a);return c.publish(c.instance,b),this.mixinMethod(b,a,c.instance.mdv,"bind"),b},mixinMethod:function(a,b,c,d){var e=function(a){return b[d].apply(this,a)};a[d]=function(){return this.mixinSuper=e,c[d].apply(this,arguments)}},inheritObject:function(a,b,c){var d=b[a]||{};b[a]=this.chainObject(d,c[a])},registerPrototype:function(a,b){var c={prototype:this.prototype},d=this.findTypeExtension(b);d&&(c.extends=d),HTMLElement.register(a,this.prototype),this.ctor=document.registerElement(a,c)},findTypeExtension:function(a){if(a&&a.indexOf("-")<0)return a;var b=this.findBasePrototype(a);return b.element?this.findTypeExtension(b.element.extends):void 0}},g={};f.chainObject=Object.__proto__?function(a,b){return a&&b&&a!==b&&(a.__proto__=b),a}:function(a,b){if(a&&b&&a!==b){var c=Object.create(b);a=e(c,a)}return a},c.declaration.prototype=f}(Polymer),function(a){function b(a){return document.contains(a)?g:f}function c(){return f.length?f[0]:g[0]}function d(a){e.waitToReady=!0,CustomElements.ready=!1,HTMLImports.whenImportsReady(function(){e.addReadyCallback(a),e.waitToReady=!1,e.check()})}var e={wait:function(a,b,c){return-1===this.indexOf(a)&&(this.add(a),a.__check=b,a.__go=c),0!==this.indexOf(a)},add:function(a){b(a).push(a)},indexOf:function(a){var c=b(a).indexOf(a);return c>=0&&document.contains(a)&&(c+=HTMLImports.useNative||HTMLImports.ready?f.length:1e9),c},go:function(a){var b=this.remove(a);b&&(b.__go.call(b),b.__check=b.__go=null,this.check())},remove:function(a){var c=this.indexOf(a);if(0===c)return b(a).shift()},check:function(){var a=this.nextElement();return a&&a.__check.call(a),this.canReady()?(this.ready(),!0):void 0},nextElement:function(){return c()},canReady:function(){return!this.waitToReady&&this.isEmpty()},isEmpty:function(){return!f.length&&!g.length},ready:function(){if(CustomElements.ready===!1&&(CustomElements.upgradeDocumentTree(document),CustomElements.ready=!0),h)for(var a;h.length;)(a=h.shift())()},addReadyCallback:function(a){a&&h.push(a)},waitToReady:!0},f=[],g=[],h=[];document.addEventListener("WebComponentsReady",function(){CustomElements.ready=!1}),a.queue=e,a.whenPolymerReady=d}(Polymer),function(a){function b(a,b){a?(document.head.appendChild(a),d(b)):b&&b()}function c(a,c){if(a&&a.length){for(var d,e,f=document.createDocumentFragment(),g=0,h=a.length;h>g&&(d=a[g]);g++)e=document.createElement("link"),e.rel="import",e.href=d,f.appendChild(e);b(f,c)}else c&&c()}var d=a.whenPolymerReady;a.import=c,a.importElements=b}(Polymer),function(a){function b(a){return Boolean(HTMLElement.getPrototypeForTag(a))}function c(a){return a&&a.indexOf("-")>=0}var d=a.extend,e=a.api,f=a.queue,g=a.whenPolymerReady,h=a.getRegisteredPrototype,i=a.waitingForPrototype,j=d(Object.create(HTMLElement.prototype),{createdCallback:function(){this.getAttribute("name")&&this.init()},init:function(){this.name=this.getAttribute("name"),this.extends=this.getAttribute("extends"),this.loadResources(),this.registerWhenReady()},registerWhenReady:function(){this.registered||this.waitingForPrototype(this.name)||this.waitingForQueue()||this.waitingForResources()||f.go(this)},_register:function(){c(this.extends)&&!b(this.extends)&&console.warn("%s is attempting to extend %s, an unregistered element or one that was not registered with Polymer.",this.name,this.extends),this.register(this.name,this.extends),this.registered=!0},waitingForPrototype:function(a){return h(a)?void 0:(i(a,this),this.handleNoScript(a),!0)},handleNoScript:function(a){if(this.hasAttribute("noscript")&&!this.noscript)if(this.noscript=!0,window.CustomElements&&!CustomElements.useNative)Polymer(a);else{var b=document.createElement("script");b.textContent="Polymer('"+a+"');",this.appendChild(b)}},waitingForResources:function(){return this._needsResources},waitingForQueue:function(){return f.wait(this,this.registerWhenReady,this._register)},loadResources:function(){this._needsResources=!0,this.loadStyles(function(){this._needsResources=!1,this.registerWhenReady()}.bind(this))}});e.publish(e.declaration,j),a.getRegisteredPrototype=h,g(function(){document.body.removeAttribute("unresolved"),document.dispatchEvent(new CustomEvent("polymer-ready",{bubbles:!0}))}),document.registerElement("polymer-element",{prototype:j})}(Polymer);
-//# sourceMappingURL=polymer.js.map
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js.map b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js.map
deleted file mode 100644
index e9c9cfa..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"polymer.js","sources":["../src/polymer.js","../src/boot.js","../src/lib/lang.js","../src/lib/job.js","../src/lib/dom.js","../src/lib/super.js","../src/lib/deserialize.js","../src/api.js","../src/instance/utils.js","../src/instance/events.js","../src/instance/attributes.js","../src/instance/properties.js","../src/instance/mdv.js","../src/instance/base.js","../src/instance/styles.js","../src/declaration/polymer.js","../src/declaration/path.js","../src/declaration/styles.js","../src/declaration/events.js","../src/declaration/properties.js","../src/declaration/attributes.js","../src/declaration/prototype.js","../src/declaration/queue.js","../src/declaration/import.js","../src/declaration/polymer-element.js"],"names":["Polymer","window","scope","extend","prototype","api","Object","getOwnPropertyNames","forEach","n","pd","getOwnPropertyDescriptor","defineProperty","value","nom","job","callback","wait","stop","Job","this","go","inContext","context","boundComplete","complete","bind","h","setTimeout","handle","clearTimeout","requestAnimationFrame","cancelAnimationFrame","call","registry","HTMLElement","register","tag","getPrototypeForTag","getPrototypeOf","document","createElement","originalStopPropagation","Event","stopPropagation","cancelBubble","apply","arguments","$super","arrayOfArgs","caller","_super","nameInThis","console","warn","memoizeSuper","fn","nextSuper","proto","name","method","p","__proto__","n$","i","l","length","d","super","deserializeValue","currentValue","inferredType","Date","typeHandlers","string","date","parse","now","boolean","number","parseFloat","parseInt","isNaN","object","JSON","replace","e","function","declaration","instance","publish","apis","utils","async","args","timeout","Platform","flush","cancelAsync","Math","round","fire","type","detail","onNode","bubbles","cancelable","node","event","CustomEvent","undefined","dispatchEvent","asyncFire","classFollows","anew","old","className","classList","remove","add","nop","nob","asyncMethod","log","logFlags","EVENT_PREFIX","events","addHostListeners","eventDelegates","keys","localName","bindable","eventName","self","PolymerExpressions","prepareEventBinding","Path","get","resolveEventHandler","model","path","getValueFrom","dispatchMethod","obj","group","groupEnd","attributes","copyInstanceAttributes","a$","_instanceAttributes","k","hasAttribute","setAttribute","takeAttributes","_publishLC","a","attributeToProperty","propertyForAttribute","search","bindPattern","match","stringValue","serializeValue","reflectPropertyToAttribute","serializedValue","removeAttribute","bindProperties","inA","inProperty","observable","LOG_BIND_PROPS","inB","inPath","v","discardChanges","setValue","Observer","defineComputedProperty","properties","observeProperties","_observeNames","pn$","_publishNames","o","_propertyObserver","CompoundObserver","addPath","observeArrayValue","observe","open","notifyPropertyChanges","newValues","oldValues","paths","called","invokeMethod","callbackName","Array","isArray","unregisterObserver","observer","ArrayObserver","registerObserver","bindProperty","property","unbindAllProperties","close","unregisterObservers","unbindProperty","o$","_observers","findEventController","parentNode","lightDomController","host","unbindNodeTree","forNodeTree","_nodeUnbindAll","unbindAll","child","firstChild","nextSibling","syntax","ctlr","mdv","instanceTemplate","template","createInstance","_elementPrepared","prepareElement","unbind","path_","bindings","mixinSuper","asyncUnbindAll","_unbound","_unbindAllJob","root","shadowRoot","olderShadowRoot","cancelUnbindAll","preventCascade","mustachePattern","isBase","hasOwnProperty","PolymerBase","preparingElements","base","created","ready","createdCallback","ownerDocument","defaultView","alwaysPrepare","shadowRoots","parseDeclarations","attachedCallback","attached","enteredView","hasBeenAttached","domReady","detachedCallback","preventDispose","detached","leftView","enteredViewCallback","leftViewCallback","enteredDocumentCallback","leftDocumentCallback","element","parseDeclaration","elementElement","fetchTemplate","shadowFromTemplate","querySelector","createShadowRoot","resetStyleInheritance","dom","appendChild","shadowRootReady","lightFromTemplate","marshalNodeReferences","PointerGestures","$","querySelectorAll","id","attributeChangedCallback","getAttribute","attributeChanged","onMutation","listener","MutationObserver","mutations","disconnect","childList","subtree","constructor","Base","shimCssText","cssText","is","selector","ShadowCSS","makeScopeSelector","STYLE_SCOPE_ATTRIBUTE","STYLE_CONTROLLER_SCOPE","styles","installControllerStyles","findStyleScope","scopeHasNamedStyle","cssTextForScope","installScopeCssText","installScopeStyle","style","s","textContent","ShadowDOMPolyfill","cssTextToScopeStyle","applyStyleToScope","_scopeStyles","getRegisteredPrototype","registerPrototype","notifyPrototype","waitingForPrototype","client","waitPrototype","registerWhenReady","prototypesByName","declarations","deliverDeclarations","resolveElementPaths","urlResolver","resolveDom","addResolvePathApi","assetPath","URL","baseURI","resolvePath","urlPath","u","href","importRuleForSheet","sheet","baseUrl","head","clone","createStyleElement","attr","cssTextFromSheet","__resource","matchesSelector","inSelector","matches","STYLE_SELECTOR","STYLE_LOADABLE_MATCH","SHEET_SELECTOR","STYLE_GLOBAL_SCOPE","SCOPE_ATTR","loadStyles","content","templateContent","convertSheetsToStyles","findLoadableStyles","styleResolver","c","s$","copySheetAttributes","replaceChild","link","loadables","push","installSheets","cacheSheets","cacheStyles","installLocalSheets","installGlobalStyles","sheets","findNodes","removeChild","filter","insertBefore","matcher","nodes","array","templateNodes","concat","styleForScope","scopeDescriptor","webkitMatchesSelector","mozMatchesSelector","parseHostEvents","delegates","addAttributeDelegates","hasEventPrefix","removeEventPrefix","trim","slice","prefixLength","inferObservers","explodeObservers","exploded","ni","names","split","optimizePropertyMaps","publishProperties","requireProperties","lowerCaseMap","map","toLowerCase","ATTRIBUTES_ATTRIBUTE","ATTRIBUTES_REGEX","inheritAttributesObjects","inheritObject","publishAttributes","accumulateInstanceAttributes","clonable","isInstanceAttribute","blackList","extends","noscript","assetpath","cache-csstext","ensurePrototypeTraversal","ancestor","extendeeName","buildPrototype","publishConstructor","extension","generateBasePrototype","desugarBeforeChaining","chainPrototypes","desugarAfterChaining","inheritMetaData","chained","chainObject","extendee","shimStyling","registerCallback","symbol","ctor","extnds","findBasePrototype","ensureBaseApi","memoizedBases","extended","create","mixinMethod","source","info","typeExtension","findTypeExtension","registerElement","indexOf","inherited","queueForElement","contains","mainQueue","importQueue","nextQueued","whenPolymerReady","queue","waitToReady","CustomElements","HTMLImports","whenImportsReady","addReadyCallback","check","__check","__go","useNative","readied","shift","nextElement","canReady","isEmpty","upgradeDocumentTree","readyCallbacks","addEventListener","importElements","elementOrFragment","importUrls","urls","url","frag","createDocumentFragment","rel","import","isRegistered","Boolean","isCustomTag","init","loadResources","registered","waitingForQueue","waitingForResources","_register","handleNoScript","script","_needsResources","body"],"mappings":"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","sourcesContent":["/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\nPolymer = {};\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// TODO(sorvell): this ensures Polymer is an object and not a function\n// Platform is currently defining it as a function to allow for async loading\n// of polymer; once we refine the loading process this likely goes away.\nif (typeof window.Polymer === 'function') {\n  Polymer = {};\n}\n\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // copy own properties from 'api' to 'prototype, with name hinting for 'super'\n  function extend(prototype, api) {\n    if (prototype && api) {\n      // use only own properties of 'api'\n      Object.getOwnPropertyNames(api).forEach(function(n) {\n        // acquire property descriptor\n        var pd = Object.getOwnPropertyDescriptor(api, n);\n        if (pd) {\n          // clone property via descriptor\n          Object.defineProperty(prototype, n, pd);\n          // cache name-of-method for 'super' engine\n          if (typeof pd.value == 'function') {\n            // hint the 'super' engine\n            pd.value.nom = n;\n          }\n        }\n      });\n    }\n    return prototype;\n  }\n  \n  // exports\n\n  scope.extend = extend;\n\n})(Polymer);\n","/* \n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  \n  // usage\n  \n  // invoke cb.call(this) in 100ms, unless the job is re-registered,\n  // which resets the timer\n  // \n  // this.myJob = this.job(this.myJob, cb, 100)\n  //\n  // returns a job handle which can be used to re-register a job\n\n  var Job = function(inContext) {\n    this.context = inContext;\n    this.boundComplete = this.complete.bind(this)\n  };\n  Job.prototype = {\n    go: function(callback, wait) {\n      this.callback = callback;\n      var h;\n      if (!wait) {\n        h = requestAnimationFrame(this.boundComplete);\n        this.handle = function() {\n          cancelAnimationFrame(h);\n        }\n      } else {\n        h = setTimeout(this.boundComplete, wait);\n        this.handle = function() {\n          clearTimeout(h);\n        }\n      }\n    },\n    stop: function() {\n      if (this.handle) {\n        this.handle();\n        this.handle = null;\n      }\n    },\n    complete: function() {\n      if (this.handle) {\n        this.stop();\n        this.callback.call(this.context);\n      }\n    }\n  };\n  \n  function job(job, callback, wait) {\n    if (job) {\n      job.stop();\n    } else {\n      job = new Job(this);\n    }\n    job.go(callback, wait);\n    return job;\n  }\n  \n  // exports \n\n  scope.job = job;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var registry = {};\n\n  HTMLElement.register = function(tag, prototype) {\n    registry[tag] = prototype;\n  }\n\n  // get prototype mapped to node <tag>\n  HTMLElement.getPrototypeForTag = function(tag) {\n    var prototype = !tag ? HTMLElement.prototype : registry[tag];\n    // TODO(sjmiles): creating <tag> is likely to have wasteful side-effects\n    return prototype || Object.getPrototypeOf(document.createElement(tag));\n  };\n\n  // we have to flag propagation stoppage for the event dispatcher\n  var originalStopPropagation = Event.prototype.stopPropagation;\n  Event.prototype.stopPropagation = function() {\n    this.cancelBubble = true;\n    originalStopPropagation.apply(this, arguments);\n  };\n  \n  // TODO(sorvell): remove when we're sure imports does not need\n  // to load stylesheets\n  /*\n  HTMLImports.importer.preloadSelectors += \n      ', polymer-element link[rel=stylesheet]';\n  */\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n (function(scope) {\n    // super\n\n    // `arrayOfArgs` is an optional array of args like one might pass\n    // to `Function.apply`\n\n    // TODO(sjmiles):\n    //    $super must be installed on an instance or prototype chain\n    //    as `super`, and invoked via `this`, e.g.\n    //      `this.super();`\n\n    //    will not work if function objects are not unique, for example,\n    //    when using mixins.\n    //    The memoization strategy assumes each function exists on only one \n    //    prototype chain i.e. we use the function object for memoizing)\n    //    perhaps we can bookkeep on the prototype itself instead\n    function $super(arrayOfArgs) {\n      // since we are thunking a method call, performance is important here: \n      // memoize all lookups, once memoized the fast path calls no other \n      // functions\n      //\n      // find the caller (cannot be `strict` because of 'caller')\n      var caller = $super.caller;\n      // memoized 'name of method' \n      var nom = caller.nom;\n      // memoized next implementation prototype\n      var _super = caller._super;\n      if (!_super) {\n        if (!nom) {\n          nom = caller.nom = nameInThis.call(this, caller);\n        }\n        if (!nom) {\n          console.warn('called super() on a method not installed declaratively (has no .nom property)');\n        }\n        // super prototype is either cached or we have to find it\n        // by searching __proto__ (at the 'top')\n        _super = memoizeSuper(caller, nom, getPrototypeOf(this));\n      }\n      if (!_super) {\n        // if _super is falsey, there is no super implementation\n        //console.warn('called $super(' + nom + ') where there is no super implementation');\n      } else {\n        // our super function\n        var fn = _super[nom];\n        // memoize information so 'fn' can call 'super'\n        if (!fn._super) {\n          memoizeSuper(fn, nom, _super);\n        }\n        // invoke the inherited method\n        // if 'fn' is not function valued, this will throw\n        return fn.apply(this, arrayOfArgs || []);\n      }\n    }\n\n    function nextSuper(proto, name, caller) {\n      // look for an inherited prototype that implements name\n      while (proto) {\n        if ((proto[name] !== caller) && proto[name]) {\n          return proto;\n        }\n        proto = getPrototypeOf(proto);\n      }\n    }\n\n    function memoizeSuper(method, name, proto) {\n      // find and cache next prototype containing `name`\n      // we need the prototype so we can do another lookup\n      // from here\n      method._super = nextSuper(proto, name, method);\n      if (method._super) {\n        // _super is a prototype, the actual method is _super[name]\n        // tag super method with it's name for further lookups\n        method._super[name].nom = name;\n      }\n      return method._super;\n    }\n\n    function nameInThis(value) {\n      var p = this.__proto__;\n      while (p && p !== HTMLElement.prototype) {\n        // TODO(sjmiles): getOwnPropertyNames is absurdly expensive\n        var n$ = Object.getOwnPropertyNames(p);\n        for (var i=0, l=n$.length, n; i<l && (n=n$[i]); i++) {\n          var d = Object.getOwnPropertyDescriptor(p, n);\n          if (typeof d.value === 'function' && d.value === value) {\n            return n;\n          }\n        }\n        p = p.__proto__;\n      }\n    }\n\n    // NOTE: In some platforms (IE10) the prototype chain is faked via \n    // __proto__. Therefore, always get prototype via __proto__ instead of\n    // the more standard Object.getPrototypeOf.\n    function getPrototypeOf(prototype) {\n      return prototype.__proto__;\n    }\n\n    // utility function to precompute name tags for functions\n    // in a (unchained) prototype\n    function hintSuper(prototype) {\n      // tag functions with their prototype name to optimize\n      // super call invocations\n      for (var n in prototype) {\n        var pd = Object.getOwnPropertyDescriptor(prototype, n);\n        if (pd && typeof pd.value === 'function') {\n          pd.value.nom = n;\n        }\n      }\n    }\n\n    // exports\n\n    scope.super = $super;\n\n})(Polymer);\n","/* \n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  var typeHandlers = {\n    string: function(value) {\n      return value;\n    },\n    date: function(value) {\n      return new Date(Date.parse(value) || Date.now());\n    },\n    boolean: function(value) {\n      if (value === '') {\n        return true;\n      }\n      return value === 'false' ? false : !!value;\n    },\n    number: function(value) {\n      var n = parseFloat(value);\n      // hex values like \"0xFFFF\" parseFloat as 0\n      if (n === 0) {\n        n = parseInt(value);\n      }\n      return isNaN(n) ? value : n;\n      // this code disabled because encoded values (like \"0xFFFF\")\n      // do not round trip to their original format\n      //return (String(floatVal) === value) ? floatVal : value;\n    },\n    object: function(value, currentValue) {\n      if (currentValue === null) {\n        return value;\n      }\n      try {\n        // If the string is an object, we can parse is with the JSON library.\n        // include convenience replace for single-quotes. If the author omits\n        // quotes altogether, parse will fail.\n        return JSON.parse(value.replace(/'/g, '\"'));\n      } catch(e) {\n        // The object isn't valid JSON, return the raw value\n        return value;\n      }\n    },\n    // avoid deserialization of functions\n    'function': function(value, currentValue) {\n      return currentValue;\n    }\n  };\n\n  function deserializeValue(value, currentValue) {\n    // attempt to infer type from default value\n    var inferredType = typeof currentValue;\n    // invent 'date' type value for Date\n    if (currentValue instanceof Date) {\n      inferredType = 'date';\n    }\n    // delegate deserialization via type string\n    return typeHandlers[inferredType](value, currentValue);\n  }\n\n  // exports\n\n  scope.deserializeValue = deserializeValue;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var extend = scope.extend;\n\n  // module\n\n  var api = {};\n\n  api.declaration = {};\n  api.instance = {};\n\n  api.publish = function(apis, prototype) {\n    for (var n in apis) {\n      extend(prototype, apis[n]);\n    }\n  }\n\n  // exports\n\n  scope.api = api;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var utils = {\n    /**\n      * Invokes a function asynchronously. The context of the callback\n      * function is bound to 'this' automatically.\n      * @method async\n      * @param {Function|String} method\n      * @param {any|Array} args\n      * @param {number} timeout\n      */\n    async: function(method, args, timeout) {\n      // when polyfilling Object.observe, ensure changes \n      // propagate before executing the async method\n      Platform.flush();\n      // second argument to `apply` must be an array\n      args = (args && args.length) ? args : [args];\n      // function to invoke\n      var fn = function() {\n        (this[method] || method).apply(this, args);\n      }.bind(this);\n      // execute `fn` sooner or later\n      var handle = timeout ? setTimeout(fn, timeout) :\n          requestAnimationFrame(fn);\n      // NOTE: switch on inverting handle to determine which time is used.\n      return timeout ? handle : 1 / handle;\n    },\n    cancelAsync: function(handle) {\n      if (handle < 1) {\n        cancelAnimationFrame(Math.round(1 / handle));\n      } else {\n        clearTimeout(handle);\n      }\n    },\n    /**\n      * Fire an event.\n      * @method fire\n      * @returns {Object} event\n      * @param {string} type An event name.\n      * @param {any} detail\n      * @param {Node} onNode Target node.\n      */\n    fire: function(type, detail, onNode, bubbles, cancelable) {\n      var node = onNode || this;\n      var detail = detail || {};\n      var event = new CustomEvent(type, {\n        bubbles: (bubbles !== undefined ? bubbles : true), \n        cancelable: (cancelable !== undefined ? cancelable : true), \n        detail: detail\n      });\n      node.dispatchEvent(event);\n      return event;\n    },\n    /**\n      * Fire an event asynchronously.\n      * @method asyncFire\n      * @param {string} type An event name.\n      * @param detail\n      * @param {Node} toNode Target node.\n      */\n    asyncFire: function(/*inType, inDetail*/) {\n      this.async(\"fire\", arguments);\n    },\n    /**\n      * Remove class from old, add class to anew, if they exist\n      * @param classFollows\n      * @param anew A node.\n      * @param old A node\n      * @param className\n      */\n    classFollows: function(anew, old, className) {\n      if (old) {\n        old.classList.remove(className);\n      }\n      if (anew) {\n        anew.classList.add(className);\n      }\n    }\n  };\n\n  // no-operation function for handy stubs\n  var nop = function() {};\n\n  // null-object for handy stubs\n  var nob = {};\n\n  // deprecated\n\n  utils.asyncMethod = utils.async;\n\n  // exports\n\n  scope.api.instance.utils = utils;\n  scope.nop = nop;\n  scope.nob = nob;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  var EVENT_PREFIX = 'on-';\n\n  // instance events api\n  var events = {\n    // read-only\n    EVENT_PREFIX: EVENT_PREFIX,\n    // event listeners on host\n    addHostListeners: function() {\n      var events = this.eventDelegates;\n      log.events && (Object.keys(events).length > 0) && console.log('[%s] addHostListeners:', this.localName, events);\n      // NOTE: host events look like bindings but really are not;\n      // (1) we don't want the attribute to be set and (2) we want to support\n      // multiple event listeners ('host' and 'instance') and Node.bind\n      // by default supports 1 thing being bound.\n      // We do, however, leverage the event hookup code in PolymerExpressions\n      // so that we have a common code path for handling declarative events.\n      var self = this, bindable, eventName;\n      for (var n in events) {\n        eventName = EVENT_PREFIX + n;\n        bindable = PolymerExpressions.prepareEventBinding(\n          Path.get(events[n]),\n          eventName, \n          {\n            resolveEventHandler: function(model, path, node) {\n              var fn = path.getValueFrom(self);\n              if (fn) {\n                return fn.bind(self);\n              }\n            }\n          }\n        );\n        bindable(this, this, false);\n      }\n    },\n    // call 'method' or function method on 'obj' with 'args', if the method exists\n    dispatchMethod: function(obj, method, args) {\n      if (obj) {\n        log.events && console.group('[%s] dispatch [%s]', obj.localName, method);\n        var fn = typeof method === 'function' ? method : obj[method];\n        if (fn) {\n          fn[args ? 'apply' : 'call'](obj, args);\n        }\n        log.events && console.groupEnd();\n        Platform.flush();\n      }\n    }\n  };\n\n  // exports\n\n  scope.api.instance.events = events;\n\n})(Polymer);\n","/*\r\n * Copyright 2013 The Polymer Authors. All rights reserved.\r\n * Use of this source code is governed by a BSD-style\r\n * license that can be found in the LICENSE file.\r\n */\r\n(function(scope) {\r\n\r\n  // instance api for attributes\r\n\r\n  var attributes = {\r\n    copyInstanceAttributes: function () {\r\n      var a$ = this._instanceAttributes;\r\n      for (var k in a$) {\r\n        if (!this.hasAttribute(k)) {\r\n          this.setAttribute(k, a$[k]);\r\n        }\r\n      }\r\n    },\r\n    // for each attribute on this, deserialize value to property as needed\r\n    takeAttributes: function() {\r\n      // if we have no publish lookup table, we have no attributes to take\r\n      // TODO(sjmiles): ad hoc\r\n      if (this._publishLC) {\r\n        for (var i=0, a$=this.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {\r\n          this.attributeToProperty(a.name, a.value);\r\n        }\r\n      }\r\n    },\r\n    // if attribute 'name' is mapped to a property, deserialize\r\n    // 'value' into that property\r\n    attributeToProperty: function(name, value) {\r\n      // try to match this attribute to a property (attributes are\r\n      // all lower-case, so this is case-insensitive search)\r\n      var name = this.propertyForAttribute(name);\r\n      if (name) {\r\n        // filter out 'mustached' values, these are to be\r\n        // replaced with bound-data and are not yet values\r\n        // themselves\r\n        if (value && value.search(scope.bindPattern) >= 0) {\r\n          return;\r\n        }\r\n        // get original value\r\n        var currentValue = this[name];\r\n        // deserialize Boolean or Number values from attribute\r\n        var value = this.deserializeValue(value, currentValue);\r\n        // only act if the value has changed\r\n        if (value !== currentValue) {\r\n          // install new value (has side-effects)\r\n          this[name] = value;\r\n        }\r\n      }\r\n    },\r\n    // return the published property matching name, or undefined\r\n    propertyForAttribute: function(name) {\r\n      var match = this._publishLC && this._publishLC[name];\r\n      //console.log('propertyForAttribute:', name, 'matches', match);\r\n      return match;\r\n    },\r\n    // convert representation of 'stringValue' based on type of 'currentValue'\r\n    deserializeValue: function(stringValue, currentValue) {\r\n      return scope.deserializeValue(stringValue, currentValue);\r\n    },\r\n    serializeValue: function(value, inferredType) {\r\n      if (inferredType === 'boolean') {\r\n        return value ? '' : undefined;\r\n      } else if (inferredType !== 'object' && inferredType !== 'function'\r\n          && value !== undefined) {\r\n        return value;\r\n      }\r\n    },\r\n    reflectPropertyToAttribute: function(name) {\r\n      var inferredType = typeof this[name];\r\n      // try to intelligently serialize property value\r\n      var serializedValue = this.serializeValue(this[name], inferredType);\r\n      // boolean properties must reflect as boolean attributes\r\n      if (serializedValue !== undefined) {\r\n        this.setAttribute(name, serializedValue);\r\n        // TODO(sorvell): we should remove attr for all properties\r\n        // that have undefined serialization; however, we will need to\r\n        // refine the attr reflection system to achieve this; pica, for example,\r\n        // relies on having inferredType object properties not removed as\r\n        // attrs.\r\n      } else if (inferredType === 'boolean') {\r\n        this.removeAttribute(name);\r\n      }\r\n    }\r\n  };\r\n\r\n  // exports\r\n\r\n  scope.api.instance.attributes = attributes;\r\n\r\n})(Polymer);\r\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n\n  // magic words\n\n  var OBSERVE_SUFFIX = 'Changed';\n\n  // element api\n\n  var empty = [];\n\n  var properties = {\n    observeProperties: function() {\n      var n$ = this._observeNames, pn$ = this._publishNames;\n      if ((n$ && n$.length) || (pn$ && pn$.length)) {\n        var self = this;\n        var o = this._propertyObserver = new CompoundObserver();\n        for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {\n          o.addPath(this, n);\n          // observer array properties\n          var pd = Object.getOwnPropertyDescriptor(this.__proto__, n);\n          if (pd && pd.value) {\n            this.observeArrayValue(n, pd.value, null);\n          }\n        }\n        for (var i=0, l=pn$.length, n; (i<l) && (n=pn$[i]); i++) {\n          if (!this.observe || (this.observe[n] === undefined)) {\n            o.addPath(this, n);\n          }\n        }\n        o.open(this.notifyPropertyChanges, this);\n      }\n    },\n    notifyPropertyChanges: function(newValues, oldValues, paths) {\n      var name, method, called = {};\n      for (var i in oldValues) {\n        // note: paths is of form [object, path, object, path]\n        name = paths[2 * i + 1];\n        if (this.publish[name] !== undefined) {\n          this.reflectPropertyToAttribute(name);\n        }\n        method = this.observe[name];\n        if (method) {\n          this.observeArrayValue(name, newValues[i], oldValues[i]);\n          if (!called[method]) {\n            called[method] = true;\n            // observes the value if it is an array\n            this.invokeMethod(method, [oldValues[i], newValues[i], arguments]);\n          }\n        }\n      }\n    },\n    observeArrayValue: function(name, value, old) {\n      // we only care if there are registered side-effects\n      var callbackName = this.observe[name];\n      if (callbackName) {\n        // if we are observing the previous value, stop\n        if (Array.isArray(old)) {\n          log.observe && console.log('[%s] observeArrayValue: unregister observer [%s]', this.localName, name);\n          this.unregisterObserver(name + '__array');\n        }\n        // if the new value is an array, being observing it\n        if (Array.isArray(value)) {\n          log.observe && console.log('[%s] observeArrayValue: register observer [%s]', this.localName, name, value);\n          var observer = new ArrayObserver(value);\n          observer.open(function(value, old) {\n            this.invokeMethod(callbackName, [old]);\n          }, this);\n          this.registerObserver(name + '__array', observer);\n        }\n      }\n    },\n    bindProperty: function(property, observable) {\n      // apply Polymer two-way reference binding\n      return bindProperties(this, property, observable);\n    },\n    unbindAllProperties: function() {\n      if (this._propertyObserver) {\n        this._propertyObserver.close();\n      }\n      this.unregisterObservers();\n    },\n    unbindProperty: function(name) {\n      return this.unregisterObserver(name);\n    },\n    invokeMethod: function(method, args) {\n      var fn = this[method] || method;\n      if (typeof fn === 'function') {\n        fn.apply(this, args);\n      }\n    },\n    // bookkeeping observers for memory management\n    registerObserver: function(name, observer) {\n      var o$ = this._observers || (this._observers = {});\n      o$[name] = observer;\n    },\n    unregisterObserver: function(name) {\n      var o$ = this._observers;\n      if (o$ && o$[name]) {\n        o$[name].close();\n        o$[name] = null;\n        return true;\n      }\n    },\n    unregisterObservers: function() {\n      if (this._observers) {\n        var keys=Object.keys(this._observers);\n        for (var i=0, l=keys.length, k, o; (i < l) && (k=keys[i]); i++) {\n          o = this._observers[k];\n          o.close();\n        }\n        this._observers = {};\n      }\n    }\n  };\n\n  // property binding\n  // bind a property in A to a path in B by converting A[property] to a\n  // getter/setter pair that accesses B[...path...]\n  function bindProperties(inA, inProperty, observable) {\n    log.bind && console.log(LOG_BIND_PROPS, inB.localName || 'object', inPath, inA.localName, inProperty);\n    // capture A's value if B's value is null or undefined,\n    // otherwise use B's value\n    // TODO(sorvell): need to review, can do with ObserverTransform\n    var v = observable.discardChanges();\n    if (v === null || v === undefined) {\n      observable.setValue(inA[inProperty]);\n    }\n    return Observer.defineComputedProperty(inA, inProperty, observable);\n  }\n\n  // logging\n  var LOG_OBSERVE = '[%s] watching [%s]';\n  var LOG_OBSERVED = '[%s#%s] watch: [%s] now [%s] was [%s]';\n  var LOG_CHANGED = '[%s#%s] propertyChanged: [%s] now [%s] was [%s]';\n  var LOG_BIND_PROPS = \"[%s]: bindProperties: [%s] to [%s].[%s]\";\n\n  // exports\n\n  scope.api.instance.properties = properties;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || 0;\n  var events = scope.api.instance.events;\n\n  var syntax = new PolymerExpressions();\n  syntax.resolveEventHandler = function(model, path, node) {\n    var ctlr = findEventController(node);\n    if (ctlr) {\n      var fn = path.getValueFrom(ctlr);\n      if (fn) {\n        return fn.bind(ctlr);\n      }\n    }\n  }\n\n  // An event controller is the host element for the shadowRoot in which \n  // the node exists, or the first ancestor with a 'lightDomController'\n  // property.\n  function findEventController(node) {\n    while (node.parentNode) {\n      if (node.lightDomController) {\n        return node;\n      }\n      node = node.parentNode;\n    }\n    return node.host;\n  };\n\n  // element api supporting mdv\n\n  var mdv = {\n    syntax: syntax,\n    instanceTemplate: function(template) {\n      return template.createInstance(this, this.syntax);\n    },\n    bind: function(name, observable, oneTime) {\n      // note: binding is a prepare signal. This allows us to be sure that any\n      // property changes that occur as a result of binding will be observed.\n      if (!this._elementPrepared) {\n        this.prepareElement();\n      }\n      var property = this.propertyForAttribute(name);\n      if (!property) {\n        // TODO(sjmiles): this mixin method must use the special form\n        // of `super` installed by `mixinMethod` in declaration/prototype.js\n        return this.mixinSuper(arguments);\n      } else {\n        // clean out the closets\n        this.unbind(name);\n        // use n-way Polymer binding\n        var observer = this.bindProperty(property, observable);\n        // stick path on observer so it's available via this.bindings\n        observer.path = observable.path_;\n        // reflect bound property to attribute when binding\n        // to ensure binding is not left on attribute if property\n        // does not update due to not changing.\n        this.reflectPropertyToAttribute(property);\n        return this.bindings[name] = observer;\n      }\n    },\n    asyncUnbindAll: function() {\n      if (!this._unbound) {\n        log.unbind && console.log('[%s] asyncUnbindAll', this.localName);\n        this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0);\n      }\n    },\n    unbindAll: function() {\n      if (!this._unbound) {\n        this.unbindAllProperties();\n        this.super();\n        // unbind shadowRoot\n        var root = this.shadowRoot;\n        while (root) {\n          unbindNodeTree(root);\n          root = root.olderShadowRoot;\n        }\n        this._unbound = true;\n      }\n    },\n    cancelUnbindAll: function(preventCascade) {\n      if (this._unbound) {\n        log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAll', this.localName);\n        return;\n      }\n      log.unbind && console.log('[%s] cancelUnbindAll', this.localName);\n      if (this._unbindAllJob) {\n        this._unbindAllJob = this._unbindAllJob.stop();\n      }\n      // cancel unbinding our shadow tree iff we're not in the process of\n      // cascading our tree (as we do, for example, when the element is inserted).\n      if (!preventCascade) {\n        forNodeTree(this.shadowRoot, function(n) {\n          if (n.cancelUnbindAll) {\n            n.cancelUnbindAll();\n          }\n        });\n      }\n    }\n  };\n\n  function unbindNodeTree(node) {\n    forNodeTree(node, _nodeUnbindAll);\n  }\n\n  function _nodeUnbindAll(node) {\n    node.unbindAll();\n  }\n\n  function forNodeTree(node, callback) {\n    if (node) {\n      callback(node);\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        forNodeTree(child, callback);\n      }\n    }\n  }\n\n  var mustachePattern = /\\{\\{([^{}]*)}}/;\n\n  // exports\n\n  scope.bindPattern = mustachePattern;\n  scope.api.instance.mdv = mdv;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n  var preparingElements = 0;\n\n  var base = {\n    PolymerBase: true,\n    job: Polymer.job,\n    super: Polymer.super,\n    // user entry point for element has had its createdCallback called\n    created: function() {\n    },\n    // user entry point for element has shadowRoot and is ready for\n    // api interaction\n    ready: function() {\n    },\n    createdCallback: function() {\n      this.created();\n      if (this.ownerDocument.defaultView || this.alwaysPrepare ||\n          preparingElements > 0) {\n        this.prepareElement();\n      }\n    },\n    // system entry point, do not override\n    prepareElement: function() {\n      this._elementPrepared = true;\n      // install shadowRoots storage\n      this.shadowRoots = {};\n      // install property observers\n      this.observeProperties();\n      // install boilerplate attributes\n      this.copyInstanceAttributes();\n      // process input attributes\n      this.takeAttributes();\n      // add event listeners\n      this.addHostListeners();\n      // guarantees that while preparing, any\n      // sub-elements are also prepared\n      preparingElements++;\n      // process declarative resources\n      this.parseDeclarations(this.__proto__);\n      // decrement semaphore\n      preparingElements--;\n      // TODO(sorvell): CE polyfill uses unresolved attribute to simulate\n      // :unresolved; remove this attribute to be compatible with native\n      // CE.\n      this.removeAttribute('unresolved');\n      // user entry point\n      this.ready();\n    },\n    attachedCallback: function() {\n      if (!this._elementPrepared) {\n        this.prepareElement();\n      }\n      this.cancelUnbindAll(true);\n      // invoke user action\n      if (this.attached) {\n        this.attached();\n      }\n      // TODO(sorvell): bc\n      if (this.enteredView) {\n        this.enteredView();\n      }\n      // NOTE: domReady can be used to access elements in dom (descendants, \n      // ancestors, siblings) such that the developer is enured to upgrade\n      // ordering. If the element definitions have loaded, domReady\n      // can be used to access upgraded elements.\n      if (!this.hasBeenAttached) {\n        this.hasBeenAttached = true;\n        if (this.domReady) {\n          this.async('domReady');\n        }\n      }\n    },\n    detachedCallback: function() {\n      if (!this.preventDispose) {\n        this.asyncUnbindAll();\n      }\n      // invoke user action\n      if (this.detached) {\n        this.detached();\n      }\n      // TODO(sorvell): bc\n      if (this.leftView) {\n        this.leftView();\n      }\n    },\n    // TODO(sorvell): bc\n    enteredViewCallback: function() {\n      this.attachedCallback();\n    },\n    // TODO(sorvell): bc\n    leftViewCallback: function() {\n      this.detachedCallback();\n    },\n    // TODO(sorvell): bc\n    enteredDocumentCallback: function() {\n      this.attachedCallback();\n    },\n    // TODO(sorvell): bc\n    leftDocumentCallback: function() {\n      this.detachedCallback();\n    },\n    // recursive ancestral <element> initialization, oldest first\n    parseDeclarations: function(p) {\n      if (p && p.element) {\n        this.parseDeclarations(p.__proto__);\n        p.parseDeclaration.call(this, p.element);\n      }\n    },\n    // parse input <element> as needed, override for custom behavior\n    parseDeclaration: function(elementElement) {\n      var template = this.fetchTemplate(elementElement);\n      if (template) {\n        var root = this.shadowFromTemplate(template);\n        this.shadowRoots[elementElement.name] = root;        \n      }\n    },\n    // return a shadow-root template (if desired), override for custom behavior\n    fetchTemplate: function(elementElement) {\n      return elementElement.querySelector('template');\n    },\n    // utility function that creates a shadow root from a <template>\n    shadowFromTemplate: function(template) {\n      if (template) {\n        // make a shadow root\n        var root = this.createShadowRoot();\n        // migrate flag(s)\n        root.resetStyleInheritance = this.resetStyleInheritance;\n        // stamp template\n        // which includes parsing and applying MDV bindings before being \n        // inserted (to avoid {{}} in attribute values)\n        // e.g. to prevent <img src=\"images/{{icon}}\"> from generating a 404.\n        var dom = this.instanceTemplate(template);\n        // append to shadow dom\n        root.appendChild(dom);\n        // perform post-construction initialization tasks on shadow root\n        this.shadowRootReady(root, template);\n        // return the created shadow root\n        return root;\n      }\n    },\n    // utility function that stamps a <template> into light-dom\n    lightFromTemplate: function(template) {\n      if (template) {\n        // TODO(sorvell): mark this element as a lightDOMController so that\n        // event listeners on bound nodes inside it will be called on it.\n        // Note, the expectation here is that events on all descendants \n        // should be handled by this element.\n        this.lightDomController = true;\n        // stamp template\n        // which includes parsing and applying MDV bindings before being \n        // inserted (to avoid {{}} in attribute values)\n        // e.g. to prevent <img src=\"images/{{icon}}\"> from generating a 404.\n        var dom = this.instanceTemplate(template);\n        // append to shadow dom\n        this.appendChild(dom);\n        // perform post-construction initialization tasks on ahem, light root\n        this.shadowRootReady(this, template);\n        // return the created shadow root\n        return dom;\n      }\n    },\n    shadowRootReady: function(root, template) {\n      // locate nodes with id and store references to them in this.$ hash\n      this.marshalNodeReferences(root);\n      // set up pointer gestures\n      PointerGestures.register(root);\n    },\n    // locate nodes with id and store references to them in this.$ hash\n    marshalNodeReferences: function(root) {\n      // establish $ instance variable\n      var $ = this.$ = this.$ || {};\n      // populate $ from nodes with ID from the LOCAL tree\n      if (root) {\n        var n$ = root.querySelectorAll(\"[id]\");\n        for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {\n          $[n.id] = n;\n        };\n      }\n    },\n    attributeChangedCallback: function(name, oldValue) {\n      // TODO(sjmiles): adhoc filter\n      if (name !== 'class' && name !== 'style') {\n        this.attributeToProperty(name, this.getAttribute(name));\n      }\n      if (this.attributeChanged) {\n        this.attributeChanged.apply(this, arguments);\n      }\n    },\n    onMutation: function(node, listener) {\n      var observer = new MutationObserver(function(mutations) {\n        listener.call(this, observer, mutations);\n        observer.disconnect();\n      }.bind(this));\n      observer.observe(node, {childList: true, subtree: true});\n    }\n  };\n\n  // true if object has own PolymerBase api\n  function isBase(object) {\n    return object.hasOwnProperty('PolymerBase') \n  }\n\n  // name a base constructor for dev tools\n\n  function PolymerBase() {};\n  PolymerBase.prototype = base;\n  base.constructor = PolymerBase;\n  \n  // exports\n\n  scope.Base = PolymerBase;\n  scope.isBase = isBase;\n  scope.api.instance.base = base;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  \n  // magic words\n  \n  var STYLE_SCOPE_ATTRIBUTE = 'element';\n  var STYLE_CONTROLLER_SCOPE = 'controller';\n  \n  var styles = {\n    STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE,\n    /**\n     * Installs external stylesheets and <style> elements with the attribute \n     * polymer-scope='controller' into the scope of element. This is intended\n     * to be a called during custom element construction.\n    */\n    installControllerStyles: function() {\n      // apply controller styles, but only if they are not yet applied\n      var scope = this.findStyleScope();\n      if (scope && !this.scopeHasNamedStyle(scope, this.localName)) {\n        // allow inherited controller styles\n        var proto = getPrototypeOf(this), cssText = '';\n        while (proto && proto.element) {\n          cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE);\n          proto = getPrototypeOf(proto);\n        }\n        if (cssText) {\n          this.installScopeCssText(cssText, scope);\n        }\n      }\n    },\n    installScopeStyle: function(style, name) {\n      var scope = this.findStyleScope(), name = name || '';\n      if (scope && !this.scopeHasNamedStyle(scope, this.localName + name)) {\n        var cssText = '';\n        if (style instanceof Array) {\n          for (var i=0, l=style.length, s; (i<l) && (s=style[i]); i++) {\n            cssText += s.textContent + '\\n\\n';\n          }\n        } else {\n          cssText = style.textContent;\n        }\n        this.installScopeCssText(cssText, scope, name);\n      }\n    },\n    installScopeCssText: function(cssText, scope, name) {\n      scope = scope || this.findStyleScope();\n      name = name || '';\n      if (!scope) {\n        return;\n      }\n      if (window.ShadowDOMPolyfill) {\n        cssText = shimCssText(cssText, scope.host);\n      }\n      var style = this.element.cssTextToScopeStyle(cssText,\n          STYLE_CONTROLLER_SCOPE);\n      Polymer.applyStyleToScope(style, scope);\n      // cache that this style has been applied\n      scope._scopeStyles[this.localName + name] = true;\n    },\n    findStyleScope: function() {\n      // find the shadow root that contains this element\n      var n = this;\n      while (n.parentNode) {\n        n = n.parentNode;\n      }\n      return n;\n    },\n    scopeHasNamedStyle: function(scope, name) {\n      scope._scopeStyles = scope._scopeStyles || {};\n      return scope._scopeStyles[name];\n    }\n  };\n  \n  // NOTE: use raw prototype traversal so that we ensure correct traversal\n  // on platforms where the protoype chain is simulated via __proto__ (IE10)\n  function getPrototypeOf(prototype) {\n    return prototype.__proto__;\n  }\n\n  function shimCssText(cssText, host) {\n    var name = '', is = false;\n    if (host) {\n      name = host.localName;\n      is = host.hasAttribute('is');\n    }\n    var selector = Platform.ShadowCSS.makeScopeSelector(name, is);\n    return Platform.ShadowCSS.shimCssText(cssText, selector);\n  }\n\n  // exports\n\n  scope.api.instance.styles = styles;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var extend = scope.extend;\n  var api = scope.api;\n\n  // imperative implementation: Polymer()\n\n  // specify an 'own' prototype for tag `name`\n  function element(name, prototype) {\n    if (getRegisteredPrototype[name]) {\n      throw 'Already registered (Polymer) prototype for element ' + name;\n    }\n    // cache the prototype\n    registerPrototype(name, prototype);\n    // notify the registrar waiting for 'name', if any\n    notifyPrototype(name);\n  }\n\n  // async prototype source\n\n  function waitingForPrototype(name, client) {\n    waitPrototype[name] = client;\n  }\n\n  var waitPrototype = {};\n\n  function notifyPrototype(name) {\n    if (waitPrototype[name]) {\n      waitPrototype[name].registerWhenReady();\n      delete waitPrototype[name];\n    }\n  }\n\n  // utility and bookkeeping\n\n  // maps tag names to prototypes, as registered with\n  // Polymer. Prototypes associated with a tag name\n  // using document.registerElement are available from\n  // HTMLElement.getPrototypeForTag().\n  // If an element was fully registered by Polymer, then\n  // Polymer.getRegisteredPrototype(name) === \n  //   HTMLElement.getPrototypeForTag(name)\n\n  var prototypesByName = {};\n\n  function registerPrototype(name, prototype) {\n    return prototypesByName[name] = prototype || {};\n  }\n\n  function getRegisteredPrototype(name) {\n    return prototypesByName[name];\n  }\n\n  // exports\n\n  scope.getRegisteredPrototype = getRegisteredPrototype;\n  scope.waitingForPrototype = waitingForPrototype;\n\n  // namespace shenanigans so we can expose our scope on the registration \n  // function\n\n  // make window.Polymer reference `element()`\n\n  window.Polymer = element;\n\n  // TODO(sjmiles): find a way to do this that is less terrible\n  // copy window.Polymer properties onto `element()`\n\n  extend(Polymer, scope);\n\n  // Under the HTMLImports polyfill, scripts in the main document\n  // do not block on imports; we want to allow calls to Polymer in the main\n  // document. Platform collects those calls until we can process them, which\n  // we do here.\n\n  var declarations = Platform.deliverDeclarations();\n  if (declarations) {\n    for (var i=0, l=declarations.length, d; (i<l) && (d=declarations[i]); i++) {\n      element.apply(null, d);\n    }\n  }\n\n})(Polymer);\n","/* \n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar path = {\n  resolveElementPaths: function(node) {\n    Platform.urlResolver.resolveDom(node);\n  },\n  addResolvePathApi: function() {\n    // let assetpath attribute modify the resolve path\n    var assetPath = this.getAttribute('assetpath') || '';\n    var root = new URL(assetPath, this.ownerDocument.baseURI);\n    this.prototype.resolvePath = function(urlPath, base) {\n      var u = new URL(urlPath, base || root);\n      return u.href;\n    };\n  }\n};\n\n// exports\nscope.api.declaration.path = path;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  var api = scope.api.instance.styles;\n  var STYLE_SCOPE_ATTRIBUTE = api.STYLE_SCOPE_ATTRIBUTE;\n\n  // magic words\n\n  var STYLE_SELECTOR = 'style';\n  var STYLE_LOADABLE_MATCH = '@import';\n  var SHEET_SELECTOR = 'link[rel=stylesheet]';\n  var STYLE_GLOBAL_SCOPE = 'global';\n  var SCOPE_ATTR = 'polymer-scope';\n\n  var styles = {\n    // returns true if resources are loading\n    loadStyles: function(callback) {\n      var content = this.templateContent();\n      if (content) {\n        this.convertSheetsToStyles(content);\n      }\n      var styles = this.findLoadableStyles(content);\n      if (styles.length) {\n        Platform.styleResolver.loadStyles(styles, callback);\n      } else if (callback) {\n        callback();\n      }\n    },\n    convertSheetsToStyles: function(root) {\n      var s$ = root.querySelectorAll(SHEET_SELECTOR);\n      for (var i=0, l=s$.length, s, c; (i<l) && (s=s$[i]); i++) {\n        c = createStyleElement(importRuleForSheet(s, this.ownerDocument.baseURI),\n            this.ownerDocument);\n        this.copySheetAttributes(c, s);\n        s.parentNode.replaceChild(c, s);\n      }\n    },\n    copySheetAttributes: function(style, link) {\n      for (var i=0, a$=link.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {\n        if (a.name !== 'rel' && a.name !== 'href') {\n          style.setAttribute(a.name, a.value);\n        }\n      }\n    },\n    findLoadableStyles: function(root) {\n      var loadables = [];\n      if (root) {\n        var s$ = root.querySelectorAll(STYLE_SELECTOR);\n        for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) {\n          if (s.textContent.match(STYLE_LOADABLE_MATCH)) {\n            loadables.push(s);\n          }\n        }\n      }\n      return loadables;\n    },\n    /**\n     * Install external stylesheets loaded in <polymer-element> elements into the \n     * element's template.\n     * @param elementElement The <element> element to style.\n     */\n    installSheets: function() {\n      this.cacheSheets();\n      this.cacheStyles();\n      this.installLocalSheets();\n      this.installGlobalStyles();\n    },\n    /**\n     * Remove all sheets from element and store for later use.\n     */\n    cacheSheets: function() {\n      this.sheets = this.findNodes(SHEET_SELECTOR);\n      this.sheets.forEach(function(s) {\n        if (s.parentNode) {\n          s.parentNode.removeChild(s);\n        }\n      });\n    },\n    cacheStyles: function() {\n      this.styles = this.findNodes(STYLE_SELECTOR + '[' + SCOPE_ATTR + ']');\n      this.styles.forEach(function(s) {\n        if (s.parentNode) {\n          s.parentNode.removeChild(s);\n        }\n      });\n    },\n    /**\n     * Takes external stylesheets loaded in an <element> element and moves\n     * their content into a <style> element inside the <element>'s template.\n     * The sheet is then removed from the <element>. This is done only so \n     * that if the element is loaded in the main document, the sheet does\n     * not become active.\n     * Note, ignores sheets with the attribute 'polymer-scope'.\n     * @param elementElement The <element> element to style.\n     */\n    installLocalSheets: function () {\n      var sheets = this.sheets.filter(function(s) {\n        return !s.hasAttribute(SCOPE_ATTR);\n      });\n      var content = this.templateContent();\n      if (content) {\n        var cssText = '';\n        sheets.forEach(function(sheet) {\n          cssText += cssTextFromSheet(sheet) + '\\n';\n        });\n        if (cssText) {\n          var style = createStyleElement(cssText, this.ownerDocument);\n          content.insertBefore(style, content.firstChild);\n        }\n      }\n    },\n    findNodes: function(selector, matcher) {\n      var nodes = this.querySelectorAll(selector).array();\n      var content = this.templateContent();\n      if (content) {\n        var templateNodes = content.querySelectorAll(selector).array();\n        nodes = nodes.concat(templateNodes);\n      }\n      return matcher ? nodes.filter(matcher) : nodes;\n    },\n    templateContent: function() {\n      var template = this.querySelector('template');\n      return template && templateContent(template);\n    },\n    /**\n     * Promotes external stylesheets and <style> elements with the attribute \n     * polymer-scope='global' into global scope.\n     * This is particularly useful for defining @keyframe rules which \n     * currently do not function in scoped or shadow style elements.\n     * (See wkb.ug/72462)\n     * @param elementElement The <element> element to style.\n    */\n    // TODO(sorvell): remove when wkb.ug/72462 is addressed.\n    installGlobalStyles: function() {\n      var style = this.styleForScope(STYLE_GLOBAL_SCOPE);\n      applyStyleToScope(style, document.head);\n    },\n    cssTextForScope: function(scopeDescriptor) {\n      var cssText = '';\n      // handle stylesheets\n      var selector = '[' + SCOPE_ATTR + '=' + scopeDescriptor + ']';\n      var matcher = function(s) {\n        return matchesSelector(s, selector);\n      };\n      var sheets = this.sheets.filter(matcher);\n      sheets.forEach(function(sheet) {\n        cssText += cssTextFromSheet(sheet) + '\\n\\n';\n      });\n      // handle cached style elements\n      var styles = this.styles.filter(matcher);\n      styles.forEach(function(style) {\n        cssText += style.textContent + '\\n\\n';\n      });\n      return cssText;\n    },\n    styleForScope: function(scopeDescriptor) {\n      var cssText = this.cssTextForScope(scopeDescriptor);\n      return this.cssTextToScopeStyle(cssText, scopeDescriptor);\n    },\n    cssTextToScopeStyle: function(cssText, scopeDescriptor) {\n      if (cssText) {\n        var style = createStyleElement(cssText);\n        style.setAttribute(STYLE_SCOPE_ATTRIBUTE, this.getAttribute('name') +\n            '-' + scopeDescriptor);\n        return style;\n      }\n    }\n  };\n\n  function importRuleForSheet(sheet, baseUrl) {\n    var href = new URL(sheet.getAttribute('href'), baseUrl).href;\n    return '@import \\'' + href + '\\';';\n  }\n\n  function applyStyleToScope(style, scope) {\n    if (style) {\n      if (scope === document) {\n        scope = document.head;\n      }\n      if (window.ShadowDOMPolyfill) {\n        scope = document.head;\n      }\n      // TODO(sorvell): necessary for IE\n      // see https://connect.microsoft.com/IE/feedback/details/790212/\n      // cloning-a-style-element-and-adding-to-document-produces\n      // -unexpected-result#details\n      // var clone = style.cloneNode(true);\n      var clone = createStyleElement(style.textContent);\n      var attr = style.getAttribute(STYLE_SCOPE_ATTRIBUTE);\n      if (attr) {\n        clone.setAttribute(STYLE_SCOPE_ATTRIBUTE, attr);\n      }\n      scope.appendChild(clone);\n    }\n  }\n\n  function createStyleElement(cssText, scope) {\n    scope = scope || document;\n    scope = scope.createElement ? scope : scope.ownerDocument;\n    var style = scope.createElement('style');\n    style.textContent = cssText;\n    return style;\n  }\n\n  function cssTextFromSheet(sheet) {\n    return (sheet && sheet.__resource) || '';\n  }\n\n  function matchesSelector(node, inSelector) {\n    if (matches) {\n      return matches.call(node, inSelector);\n    }\n  }\n  var p = HTMLElement.prototype;\n  var matches = p.matches || p.matchesSelector || p.webkitMatchesSelector \n      || p.mozMatchesSelector;\n  \n  // exports\n\n  scope.api.declaration.styles = styles;\n  scope.applyStyleToScope = applyStyleToScope;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  var api = scope.api.instance.events;\n  var EVENT_PREFIX = api.EVENT_PREFIX;\n  // polymer-element declarative api: events feature\n\n  var events = { \n    parseHostEvents: function() {\n      // our delegates map\n      var delegates = this.prototype.eventDelegates;\n      // extract data from attributes into delegates\n      this.addAttributeDelegates(delegates);\n    },\n    addAttributeDelegates: function(delegates) {\n      // for each attribute\n      for (var i=0, a; a=this.attributes[i]; i++) {\n        // does it have magic marker identifying it as an event delegate?\n        if (this.hasEventPrefix(a.name)) {\n          // if so, add the info to delegates\n          delegates[this.removeEventPrefix(a.name)] = a.value.replace('{{', '')\n              .replace('}}', '').trim();\n        }\n      }\n    },\n    // starts with 'on-'\n    hasEventPrefix: function (n) {\n      return n && (n[0] === 'o') && (n[1] === 'n') && (n[2] === '-');\n    },\n    removeEventPrefix: function(n) {\n      return n.slice(prefixLength);\n    }\n  };\n\n  var prefixLength = EVENT_PREFIX.length;\n\n  // exports\n  scope.api.declaration.events = events;\n\n})(Polymer);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // element api\n\n  var properties = {\n    inferObservers: function(prototype) {\n      // called before prototype.observe is chained to inherited object\n      var observe = prototype.observe, property;\n      for (var n in prototype) {\n        if (n.slice(-7) === 'Changed') {\n          if (!observe) {\n            observe  = (prototype.observe = {});\n          }\n          property = n.slice(0, -7)\n          observe[property] = observe[property] || n;\n        }\n      }\n    },\n    explodeObservers: function(prototype) {\n      // called before prototype.observe is chained to inherited object\n      var o = prototype.observe;\n      if (o) {\n        var exploded = {};\n        for (var n in o) {\n          var names = n.split(' ');\n          for (var i=0, ni; ni=names[i]; i++) {\n            exploded[ni] = o[n];\n          }\n        }\n        prototype.observe = exploded;\n      }\n    },\n    optimizePropertyMaps: function(prototype) {\n      if (prototype.observe) {\n        // construct name list\n        var a = prototype._observeNames = [];\n        for (var n in prototype.observe) {\n          var names = n.split(' ');\n          for (var i=0, ni; ni=names[i]; i++) {\n            a.push(ni);\n          }\n          //a.push(n);\n        }\n      }\n      if (prototype.publish) {\n        // construct name list\n        var a = prototype._publishNames = [];\n        for (var n in prototype.publish) {\n          a.push(n);\n        }\n      }\n    },\n    publishProperties: function(prototype, base) {\n      // if we have any properties to publish\n      var publish = prototype.publish;\n      if (publish) {\n        // transcribe `publish` entries onto own prototype\n        this.requireProperties(publish, prototype, base);\n        // construct map of lower-cased property names\n        prototype._publishLC = this.lowerCaseMap(publish);\n      }\n    },\n    requireProperties: function(properties, prototype, base) {\n      // ensure a prototype value for each property\n      for (var n in properties) {\n        if (prototype[n] === undefined && base[n] === undefined) {\n          prototype[n] = properties[n];\n        }\n      }\n    },\n    lowerCaseMap: function(properties) {\n      var map = {};\n      for (var n in properties) {\n        map[n.toLowerCase()] = n;\n      }\n      return map;\n    }\n  };\n\n  // exports\n\n  scope.api.declaration.properties = properties;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // magic words\n\n  var ATTRIBUTES_ATTRIBUTE = 'attributes';\n  var ATTRIBUTES_REGEX = /\\s|,/;\n\n  // attributes api\n\n  var attributes = {\n    inheritAttributesObjects: function(prototype) {\n      // chain our lower-cased publish map to the inherited version\n      this.inheritObject(prototype, 'publishLC');\n      // chain our instance attributes map to the inherited version\n      this.inheritObject(prototype, '_instanceAttributes');\n    },\n    publishAttributes: function(prototype, base) {\n      // merge names from 'attributes' attribute\n      var attributes = this.getAttribute(ATTRIBUTES_ATTRIBUTE);\n      if (attributes) {\n        // get properties to publish\n        var publish = prototype.publish || (prototype.publish = {});\n        // names='a b c' or names='a,b,c'\n        var names = attributes.split(ATTRIBUTES_REGEX);\n        // record each name for publishing\n        for (var i=0, l=names.length, n; i<l; i++) {\n          // remove excess ws\n          n = names[i].trim();\n          // do not override explicit entries\n          if (n && publish[n] === undefined && base[n] === undefined) {\n            publish[n] = null;\n          }\n        }\n      }\n    },\n    // record clonable attributes from <element>\n    accumulateInstanceAttributes: function() {\n      // inherit instance attributes\n      var clonable = this.prototype._instanceAttributes;\n      // merge attributes from element\n      var a$ = this.attributes;\n      for (var i=0, l=a$.length, a; (i<l) && (a=a$[i]); i++) {  \n        if (this.isInstanceAttribute(a.name)) {\n          clonable[a.name] = a.value;\n        }\n      }\n    },\n    isInstanceAttribute: function(name) {\n      return !this.blackList[name] && name.slice(0,3) !== 'on-';\n    },\n    // do not clone these attributes onto instances\n    blackList: {\n      name: 1,\n      'extends': 1,\n      constructor: 1,\n      noscript: 1,\n      assetpath: 1,\n      'cache-csstext': 1\n    }\n  };\n\n  // add ATTRIBUTES_ATTRIBUTE to the blacklist\n  attributes.blackList[ATTRIBUTES_ATTRIBUTE] = 1;\n\n  // exports\n\n  scope.api.declaration.attributes = attributes;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n  \n  var api = scope.api;\n  var isBase = scope.isBase;\n  var extend = scope.extend;\n\n  // prototype api\n\n  var prototype = {\n\n    register: function(name, extendeeName) {\n      // build prototype combining extendee, Polymer base, and named api\n      this.buildPrototype(name, extendeeName);\n      // register our custom element with the platform\n      this.registerPrototype(name, extendeeName);\n      // reference constructor in a global named by 'constructor' attribute\n      this.publishConstructor();\n    },\n\n    buildPrototype: function(name, extendeeName) {\n      // get our custom prototype (before chaining)\n      var extension = scope.getRegisteredPrototype(name);\n      // get basal prototype\n      var base = this.generateBasePrototype(extendeeName);\n      // implement declarative features\n      this.desugarBeforeChaining(extension, base);\n      // join prototypes\n      this.prototype = this.chainPrototypes(extension, base);\n      // more declarative features\n      this.desugarAfterChaining(name, extendeeName);\n    },\n\n    desugarBeforeChaining: function(prototype, base) {\n      // back reference declaration element\n      // TODO(sjmiles): replace `element` with `elementElement` or `declaration`\n      prototype.element = this;\n      // transcribe `attributes` declarations onto own prototype's `publish`\n      this.publishAttributes(prototype, base);\n      // `publish` properties to the prototype and to attribute watch\n      this.publishProperties(prototype, base);\n      // infer observers for `observe` list based on method names\n      this.inferObservers(prototype);\n      // desugar compound observer syntax, e.g. 'a b c' \n      this.explodeObservers(prototype);\n    },\n\n    chainPrototypes: function(prototype, base) {\n      // chain various meta-data objects to inherited versions\n      this.inheritMetaData(prototype, base);\n      // chain custom api to inherited\n      var chained = this.chainObject(prototype, base);\n      // x-platform fixup\n      ensurePrototypeTraversal(chained);\n      return chained;\n    },\n\n    inheritMetaData: function(prototype, base) {\n      // chain observe object to inherited\n      this.inheritObject('observe', prototype, base);\n      // chain publish object to inherited\n      this.inheritObject('publish', prototype, base);\n      // chain our lower-cased publish map to the inherited version\n      this.inheritObject('_publishLC', prototype, base);\n      // chain our instance attributes map to the inherited version\n      this.inheritObject('_instanceAttributes', prototype, base);\n      // chain our event delegates map to the inherited version\n      this.inheritObject('eventDelegates', prototype, base);\n    },\n\n    // implement various declarative features\n    desugarAfterChaining: function(name, extendee) {\n      // build side-chained lists to optimize iterations\n      this.optimizePropertyMaps(this.prototype);\n      // install external stylesheets as if they are inline\n      this.installSheets();\n      // adjust any paths in dom from imports\n      this.resolveElementPaths(this);\n      // compile list of attributes to copy to instances\n      this.accumulateInstanceAttributes();\n      // parse on-* delegates declared on `this` element\n      this.parseHostEvents();\n      //\n      // install a helper method this.resolvePath to aid in \n      // setting resource urls. e.g.\n      // this.$.image.src = this.resolvePath('images/foo.png')\n      this.addResolvePathApi();\n      // under ShadowDOMPolyfill, transforms to approximate missing CSS features\n      if (window.ShadowDOMPolyfill) {\n        Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);\n      }\n      // allow custom element access to the declarative context\n      if (this.prototype.registerCallback) {\n        this.prototype.registerCallback(this);\n      }\n    },\n\n    // if a named constructor is requested in element, map a reference\n    // to the constructor to the given symbol\n    publishConstructor: function() {\n      var symbol = this.getAttribute('constructor');\n      if (symbol) {\n        window[symbol] = this.ctor;\n      }\n    },\n\n    // build prototype combining extendee, Polymer base, and named api\n    generateBasePrototype: function(extnds) {\n      var prototype = this.findBasePrototype(extnds);\n      if (!prototype) {\n        // create a prototype based on tag-name extension\n        var prototype = HTMLElement.getPrototypeForTag(extnds);\n        // insert base api in inheritance chain (if needed)\n        prototype = this.ensureBaseApi(prototype);\n        // memoize this base\n        memoizedBases[extnds] = prototype;\n      }\n      return prototype;\n    },\n\n    findBasePrototype: function(name) {\n      return memoizedBases[name];\n    },\n\n    // install Polymer instance api into prototype chain, as needed \n    ensureBaseApi: function(prototype) {\n      if (prototype.PolymerBase) {\n        return prototype;\n      }\n      var extended = Object.create(prototype);\n      // we need a unique copy of base api for each base prototype\n      // therefore we 'extend' here instead of simply chaining\n      api.publish(api.instance, extended);\n      // TODO(sjmiles): sharing methods across prototype chains is\n      // not supported by 'super' implementation which optimizes\n      // by memoizing prototype relationships.\n      // Probably we should have a version of 'extend' that is \n      // share-aware: it could study the text of each function,\n      // look for usage of 'super', and wrap those functions in\n      // closures.\n      // As of now, there is only one problematic method, so \n      // we just patch it manually.\n      // To avoid re-entrancy problems, the special super method\n      // installed is called `mixinSuper` and the mixin method\n      // must use this method instead of the default `super`.\n      this.mixinMethod(extended, prototype, api.instance.mdv, 'bind');\n      // return buffed-up prototype\n      return extended;\n    },\n\n    mixinMethod: function(extended, prototype, api, name) {\n      var $super = function(args) {\n        return prototype[name].apply(this, args);\n      };\n      extended[name] = function() {\n        this.mixinSuper = $super;\n        return api[name].apply(this, arguments);\n      }\n    },\n\n    // ensure prototype[name] inherits from a prototype.prototype[name]\n    inheritObject: function(name, prototype, base) {\n      // require an object\n      var source = prototype[name] || {};\n      // chain inherited properties onto a new object\n      prototype[name] = this.chainObject(source, base[name]);\n    },\n\n    // register 'prototype' to custom element 'name', store constructor \n    registerPrototype: function(name, extendee) { \n      var info = {\n        prototype: this.prototype\n      }\n      // native element must be specified in extends\n      var typeExtension = this.findTypeExtension(extendee);\n      if (typeExtension) {\n        info.extends = typeExtension;\n      }\n      // register the prototype with HTMLElement for name lookup\n      HTMLElement.register(name, this.prototype);\n      // register the custom type\n      this.ctor = document.registerElement(name, info);\n    },\n\n    findTypeExtension: function(name) {\n      if (name && name.indexOf('-') < 0) {\n        return name;\n      } else {\n        var p = this.findBasePrototype(name);\n        if (p.element) {\n          return this.findTypeExtension(p.element.extends);\n        }\n      }\n    }\n\n  };\n\n  // memoize base prototypes\n  var memoizedBases = {};\n\n  // implementation of 'chainObject' depends on support for __proto__\n  if (Object.__proto__) {\n    prototype.chainObject = function(object, inherited) {\n      if (object && inherited && object !== inherited) {\n        object.__proto__ = inherited;\n      }\n      return object;\n    }\n  } else {\n    prototype.chainObject = function(object, inherited) {\n      if (object && inherited && object !== inherited) {\n        var chained = Object.create(inherited);\n        object = extend(chained, object);\n      }\n      return object;\n    }\n  }\n\n  // On platforms that do not support __proto__ (versions of IE), the prototype\n  // chain of a custom element is simulated via installation of __proto__.\n  // Although custom elements manages this, we install it here so it's\n  // available during desugaring.\n  function ensurePrototypeTraversal(prototype) {\n    if (!Object.__proto__) {\n      var ancestor = Object.getPrototypeOf(prototype);\n      prototype.__proto__ = ancestor;\n      if (isBase(ancestor)) {\n        ancestor.__proto__ = Object.getPrototypeOf(ancestor);\n      }\n    }\n  }\n\n  // exports\n\n  api.declaration.prototype = prototype;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var queue = {\n    // tell the queue to wait for an element to be ready\n    wait: function(element, check, go) {\n      if (this.indexOf(element) === -1) {\n        this.add(element);\n        element.__check = check;\n        element.__go = go;\n      }\n      return (this.indexOf(element) !== 0);\n    },\n    add: function(element) {\n      //console.log('queueing', element.name);\n      queueForElement(element).push(element);\n    },\n    indexOf: function(element) {\n      var i = queueForElement(element).indexOf(element);\n      if (i >= 0 && document.contains(element)) {\n        i += (HTMLImports.useNative || HTMLImports.ready) ? importQueue.length :\n            1e9;\n      }\n      return i;  \n    },\n    // tell the queue an element is ready to be registered\n    go: function(element) {\n      var readied = this.remove(element);\n      if (readied) {\n        readied.__go.call(readied);\n        readied.__check = readied.__go = null;\n        this.check();\n      }\n    },\n    remove: function(element) {\n      var i = this.indexOf(element);\n      if (i !== 0) {\n        //console.warn('queue order wrong', i);\n        return;\n      }\n      return queueForElement(element).shift();  \n    },\n    check: function() {\n      // next\n      var element = this.nextElement();\n      if (element) {\n        element.__check.call(element);\n      }\n      if (this.canReady()) {\n        this.ready();\n        return true;\n      }\n    },\n    nextElement: function() {\n      return nextQueued();\n    },\n    canReady: function() {\n      return !this.waitToReady && this.isEmpty();\n    },\n    isEmpty: function() {\n      return !importQueue.length && !mainQueue.length;\n    },\n    ready: function() {\n      // TODO(sorvell): As an optimization, turn off CE polyfill upgrading\n      // while registering. This way we avoid having to upgrade each document\n      // piecemeal per registration and can instead register all elements\n      // and upgrade once in a batch. Without this optimization, upgrade time\n      // degrades significantly when SD polyfill is used. This is mainly because\n      // querying the document tree for elements is slow under the SD polyfill.\n      if (CustomElements.ready === false) {\n        CustomElements.upgradeDocumentTree(document);\n        CustomElements.ready = true;\n      }\n      if (readyCallbacks) {\n        var fn;\n        while (readyCallbacks.length) {\n          fn = readyCallbacks.shift();\n          fn();\n        }\n      }\n    },\n    addReadyCallback: function(callback) {\n      if (callback) {\n        readyCallbacks.push(callback);\n      }\n    },\n    waitToReady: true\n  };\n\n  var importQueue = [];\n  var mainQueue = [];\n  var readyCallbacks = [];\n\n  function queueForElement(element) {\n    return document.contains(element) ? mainQueue : importQueue;\n  }\n\n  function nextQueued() {\n    return importQueue.length ? importQueue[0] : mainQueue[0];\n  }\n\n  var polymerReadied = false; \n\n  document.addEventListener('WebComponentsReady', function() {\n    CustomElements.ready = false;\n  });\n  \n  function whenPolymerReady(callback) {\n    queue.waitToReady = true;\n    CustomElements.ready = false;\n    HTMLImports.whenImportsReady(function() {\n      queue.addReadyCallback(callback);\n      queue.waitToReady = false;\n      queue.check();\n    });\n  }\n\n  // exports\n  scope.queue = queue;\n  scope.whenPolymerReady = whenPolymerReady;\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var whenPolymerReady = scope.whenPolymerReady;\n\n  function importElements(elementOrFragment, callback) {\n    if (elementOrFragment) {\n      document.head.appendChild(elementOrFragment);\n      whenPolymerReady(callback);\n    } else if (callback) {\n      callback();\n    }\n  }\n\n  function importUrls(urls, callback) {\n    if (urls && urls.length) {\n        var frag = document.createDocumentFragment();\n        for (var i=0, l=urls.length, url, link; (i<l) && (url=urls[i]); i++) {\n          link = document.createElement('link');\n          link.rel = 'import';\n          link.href = url;\n          frag.appendChild(link);\n        }\n        importElements(frag, callback);\n    } else if (callback) {\n      callback();\n    }\n  }\n\n  // exports\n  scope.import = importUrls;\n  scope.importElements = importElements;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var extend = scope.extend;\n  var api = scope.api;\n  var queue = scope.queue;\n  var whenPolymerReady = scope.whenPolymerReady;\n  var getRegisteredPrototype = scope.getRegisteredPrototype;\n  var waitingForPrototype = scope.waitingForPrototype;\n\n  // declarative implementation: <polymer-element>\n\n  var prototype = extend(Object.create(HTMLElement.prototype), {\n\n    createdCallback: function() {\n      if (this.getAttribute('name')) {\n        this.init();\n      }\n    },\n\n    init: function() {\n      // fetch declared values\n      this.name = this.getAttribute('name');\n      this.extends = this.getAttribute('extends');\n      // initiate any async resource fetches\n      this.loadResources();\n      // register when all constraints are met\n      this.registerWhenReady();\n    },\n\n    registerWhenReady: function() {\n     if (this.registered\n       || this.waitingForPrototype(this.name)\n       || this.waitingForQueue()\n       || this.waitingForResources()) {\n          return;\n      }\n      queue.go(this);\n    },\n\n\n    // TODO(sorvell): refactor, this method is private-ish, but it's being\n    // called by the queue object.\n    _register: function() {\n      //console.log('registering', this.name);\n      //console.group('registering', this.name);\n      // warn if extending from a custom element not registered via Polymer\n      if (isCustomTag(this.extends) && !isRegistered(this.extends)) {\n        console.warn('%s is attempting to extend %s, an unregistered element ' +\n            'or one that was not registered with Polymer.', this.name,\n            this.extends);\n      }\n      this.register(this.name, this.extends);\n      this.registered = true;\n      //console.groupEnd();\n    },\n\n    waitingForPrototype: function(name) {\n      if (!getRegisteredPrototype(name)) {\n        // then wait for a prototype\n        waitingForPrototype(name, this);\n        // emulate script if user is not supplying one\n        this.handleNoScript(name);\n        // prototype not ready yet\n        return true;\n      }\n    },\n\n    handleNoScript: function(name) {\n      // if explicitly marked as 'noscript'\n      if (this.hasAttribute('noscript') && !this.noscript) {\n        this.noscript = true;\n        // TODO(sorvell): CustomElements polyfill awareness:\n        // noscript elements should upgrade in logical order\n        // script injection ensures this under native custom elements;\n        // under imports + ce polyfills, scripts run before upgrades.\n        // dependencies should be ready at upgrade time so register\n        // prototype at this time.\n        if (window.CustomElements && !CustomElements.useNative) {\n          Polymer(name);\n        } else {\n          var script = document.createElement('script');\n          script.textContent = 'Polymer(\\'' + name + '\\');';\n          this.appendChild(script);\n        }\n      }\n    },\n\n    waitingForResources: function() {\n      return this._needsResources;\n    },\n\n    // NOTE: Elements must be queued in proper order for inheritance/composition\n    // dependency resolution. Previously this was enforced for inheritance,\n    // and by rule for composition. It's now entirely by rule.\n    waitingForQueue: function() {\n      return queue.wait(this, this.registerWhenReady, this._register);\n    },\n\n    loadResources: function() {\n      this._needsResources = true;\n      this.loadStyles(function() {\n        this._needsResources = false;\n        this.registerWhenReady();\n      }.bind(this));\n    }\n\n  });\n\n  // semi-pluggable APIs \n\n  // TODO(sjmiles): should be fully pluggable (aka decoupled, currently\n  // the various plugins are allowed to depend on each other directly)\n  api.publish(api.declaration, prototype);\n\n  // utility and bookkeeping\n\n  function isRegistered(name) {\n    return Boolean(HTMLElement.getPrototypeForTag(name));\n  }\n\n  function isCustomTag(name) {\n    return (name && name.indexOf('-') >= 0);\n  }\n\n  // exports\n\n  scope.getRegisteredPrototype = getRegisteredPrototype;\n  \n  // boot tasks\n\n  whenPolymerReady(function() {\n    document.body.removeAttribute('unresolved');\n    document.dispatchEvent(\n      new CustomEvent('polymer-ready', {bubbles: true})\n    );\n  });\n\n  // register polymer-element with document\n\n  document.registerElement('polymer-element', {prototype: prototype});\n\n})(Polymer);\n"]}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/.bower.json
deleted file mode 100644
index 16d4ea6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/.bower.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "todomvc-common",
-  "version": "0.1.9",
-  "homepage": "https://github.com/tastejs/todomvc-common",
-  "_release": "0.1.9",
-  "_resolution": {
-    "type": "version",
-    "tag": "v0.1.9",
-    "commit": "7dd61b0ebf56c020e719a69444442cc7ae7242ff"
-  },
-  "_source": "git://github.com/tastejs/todomvc-common.git",
-  "_target": "~0.1.4",
-  "_originalSource": "todomvc-common"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.css b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.css
deleted file mode 100644
index d151ede..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.css
+++ /dev/null
@@ -1,556 +0,0 @@
-html,
-body {
-	margin: 0;
-	padding: 0;
-}
-
-button {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background: none;
-	font-size: 100%;
-	vertical-align: baseline;
-	font-family: inherit;
-	color: inherit;
-	-webkit-appearance: none;
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-body {
-	font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
-	line-height: 1.4em;
-	background: #eaeaea url('bg.png');
-	color: #4d4d4d;
-	width: 550px;
-	margin: 0 auto;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-button,
-input[type="checkbox"] {
-  outline: none;
-}
-
-#todoapp {
-	background: #fff;
-	background: rgba(255, 255, 255, 0.9);
-	margin: 130px 0 40px 0;
-	border: 1px solid #ccc;
-	position: relative;
-	border-top-left-radius: 2px;
-	border-top-right-radius: 2px;
-	box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
-				0 25px 50px 0 rgba(0, 0, 0, 0.15);
-}
-
-#todoapp:before {
-	content: '';
-	border-left: 1px solid #f5d6d6;
-	border-right: 1px solid #f5d6d6;
-	width: 2px;
-	position: absolute;
-	top: 0;
-	left: 40px;
-	height: 100%;
-}
-
-#todoapp input::-webkit-input-placeholder {
-	font-style: italic;
-}
-
-#todoapp input::-moz-placeholder {
-	font-style: italic;
-	color: #a9a9a9;
-}
-
-#todoapp h1 {
-	position: absolute;
-	top: -120px;
-	width: 100%;
-	font-size: 70px;
-	font-weight: bold;
-	text-align: center;
-	color: #b3b3b3;
-	color: rgba(255, 255, 255, 0.3);
-	text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-	-webkit-text-rendering: optimizeLegibility;
-	-moz-text-rendering: optimizeLegibility;
-	-ms-text-rendering: optimizeLegibility;
-	-o-text-rendering: optimizeLegibility;
-	text-rendering: optimizeLegibility;
-}
-
-#header {
-	padding-top: 15px;
-	border-radius: inherit;
-}
-
-#header:before {
-	content: '';
-	position: absolute;
-	top: 0;
-	right: 0;
-	left: 0;
-	height: 15px;
-	z-index: 2;
-	border-bottom: 1px solid #6c615c;
-	background: #8d7d77;
-	background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
-	background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
-	border-top-left-radius: 1px;
-	border-top-right-radius: 1px;
-}
-
-#new-todo,
-.edit {
-	position: relative;
-	margin: 0;
-	width: 100%;
-	font-size: 24px;
-	font-family: inherit;
-	line-height: 1.4em;
-	border: 0;
-	outline: none;
-	color: inherit;
-	padding: 6px;
-	border: 1px solid #999;
-	box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	box-sizing: border-box;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-#new-todo {
-	padding: 16px 16px 16px 60px;
-	border: none;
-	background: rgba(0, 0, 0, 0.02);
-	z-index: 2;
-	box-shadow: none;
-}
-
-#main {
-	position: relative;
-	z-index: 2;
-	border-top: 1px dotted #adadad;
-}
-
-label[for='toggle-all'] {
-	display: none;
-}
-
-#toggle-all {
-	position: absolute;
-	top: -42px;
-	left: -4px;
-	width: 40px;
-	text-align: center;
-	/* Mobile Safari */
-	border: none;
-}
-
-#toggle-all:before {
-	content: '»';
-	font-size: 28px;
-	color: #d9d9d9;
-	padding: 0 25px 7px;
-}
-
-#toggle-all:checked:before {
-	color: #737373;
-}
-
-#todo-list {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-}
-
-#todo-list li {
-	position: relative;
-	font-size: 24px;
-	border-bottom: 1px dotted #ccc;
-}
-
-#todo-list li:last-child {
-	border-bottom: none;
-}
-
-#todo-list li.editing {
-	border-bottom: none;
-	padding: 0;
-}
-
-#todo-list li.editing .edit {
-	display: block;
-	width: 506px;
-	padding: 13px 17px 12px 17px;
-	margin: 0 0 0 43px;
-}
-
-#todo-list li.editing .view {
-	display: none;
-}
-
-#todo-list li .toggle {
-	text-align: center;
-	width: 40px;
-	/* auto, since non-WebKit browsers doesn't support input styling */
-	height: auto;
-	position: absolute;
-	top: 0;
-	bottom: 0;
-	margin: auto 0;
-	/* Mobile Safari */
-	border: none;
-	-webkit-appearance: none;
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-#todo-list li .toggle:after {
-	content: '✔';
-	/* 40 + a couple of pixels visual adjustment */
-	line-height: 43px;
-	font-size: 20px;
-	color: #d9d9d9;
-	text-shadow: 0 -1px 0 #bfbfbf;
-}
-
-#todo-list li .toggle:checked:after {
-	color: #85ada7;
-	text-shadow: 0 1px 0 #669991;
-	bottom: 1px;
-	position: relative;
-}
-
-#todo-list li label {
-	white-space: pre;
-	word-break: break-word;
-	padding: 15px 60px 15px 15px;
-	margin-left: 45px;
-	display: block;
-	line-height: 1.2;
-	-webkit-transition: color 0.4s;
-	transition: color 0.4s;
-}
-
-#todo-list li.completed label {
-	color: #a9a9a9;
-	text-decoration: line-through;
-}
-
-#todo-list li .destroy {
-	display: none;
-	position: absolute;
-	top: 0;
-	right: 10px;
-	bottom: 0;
-	width: 40px;
-	height: 40px;
-	margin: auto 0;
-	font-size: 22px;
-	color: #a88a8a;
-	-webkit-transition: all 0.2s;
-	transition: all 0.2s;
-}
-
-#todo-list li .destroy:hover {
-	text-shadow: 0 0 1px #000,
-				 0 0 10px rgba(199, 107, 107, 0.8);
-	-webkit-transform: scale(1.3);
-	-ms-transform: scale(1.3);
-	transform: scale(1.3);
-}
-
-#todo-list li .destroy:after {
-	content: '✖';
-}
-
-#todo-list li:hover .destroy {
-	display: block;
-}
-
-#todo-list li .edit {
-	display: none;
-}
-
-#todo-list li.editing:last-child {
-	margin-bottom: -1px;
-}
-
-#footer {
-	color: #777;
-	padding: 0 15px;
-	position: absolute;
-	right: 0;
-	bottom: -31px;
-	left: 0;
-	height: 20px;
-	z-index: 1;
-	text-align: center;
-}
-
-#footer:before {
-	content: '';
-	position: absolute;
-	right: 0;
-	bottom: 31px;
-	left: 0;
-	height: 50px;
-	z-index: -1;
-	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
-				0 6px 0 -3px rgba(255, 255, 255, 0.8),
-				0 7px 1px -3px rgba(0, 0, 0, 0.3),
-				0 43px 0 -6px rgba(255, 255, 255, 0.8),
-				0 44px 2px -6px rgba(0, 0, 0, 0.2);
-}
-
-#todo-count {
-	float: left;
-	text-align: left;
-}
-
-#filters {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-	position: absolute;
-	right: 0;
-	left: 0;
-}
-
-#filters li {
-	display: inline;
-}
-
-#filters li a {
-	color: #83756f;
-	margin: 2px;
-	text-decoration: none;
-}
-
-#filters li a.selected {
-	font-weight: bold;
-}
-
-#clear-completed {
-	float: right;
-	position: relative;
-	line-height: 20px;
-	text-decoration: none;
-	background: rgba(0, 0, 0, 0.1);
-	font-size: 11px;
-	padding: 0 10px;
-	border-radius: 3px;
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
-}
-
-#clear-completed:hover {
-	background: rgba(0, 0, 0, 0.15);
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
-}
-
-#info {
-	margin: 65px auto 0;
-	color: #a6a6a6;
-	font-size: 12px;
-	text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-	text-align: center;
-}
-
-#info a {
-	color: inherit;
-}
-
-/*
-	Hack to remove background from Mobile Safari.
-	Can't use it globally since it destroys checkboxes in Firefox and Opera
-*/
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-	#toggle-all,
-	#todo-list li .toggle {
-		background: none;
-	}
-
-	#todo-list li .toggle {
-		height: 40px;
-	}
-
-	#toggle-all {
-		top: -56px;
-		left: -15px;
-		width: 65px;
-		height: 41px;
-		-webkit-transform: rotate(90deg);
-		-ms-transform: rotate(90deg);
-		transform: rotate(90deg);
-		-webkit-appearance: none;
-		appearance: none;
-	}
-}
-
-.hidden {
-	display: none;
-}
-
-hr {
-	margin: 20px 0;
-	border: 0;
-	border-top: 1px dashed #C5C5C5;
-	border-bottom: 1px dashed #F7F7F7;
-}
-
-.learn a {
-	font-weight: normal;
-	text-decoration: none;
-	color: #b83f45;
-}
-
-.learn a:hover {
-	text-decoration: underline;
-	color: #787e7e;
-}
-
-.learn h3,
-.learn h4,
-.learn h5 {
-	margin: 10px 0;
-	font-weight: 500;
-	line-height: 1.2;
-	color: #000;
-}
-
-.learn h3 {
-	font-size: 24px;
-}
-
-.learn h4 {
-	font-size: 18px;
-}
-
-.learn h5 {
-	margin-bottom: 0;
-	font-size: 14px;
-}
-
-.learn ul {
-	padding: 0;
-	margin: 0 0 30px 25px;
-}
-
-.learn li {
-	line-height: 20px;
-}
-
-.learn p {
-	font-size: 15px;
-	font-weight: 300;
-	line-height: 1.3;
-	margin-top: 0;
-	margin-bottom: 0;
-}
-
-.quote {
-	border: none;
-	margin: 20px 0 60px 0;
-}
-
-.quote p {
-	font-style: italic;
-}
-
-.quote p:before {
-	content: '“';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	top: -20px;
-	left: 3px;
-}
-
-.quote p:after {
-	content: '”';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	bottom: -42px;
-	right: 3px;
-}
-
-.quote footer {
-	position: absolute;
-	bottom: -40px;
-	right: 0;
-}
-
-.quote footer img {
-	border-radius: 3px;
-}
-
-.quote footer a {
-	margin-left: 5px;
-	vertical-align: middle;
-}
-
-.speech-bubble {
-	position: relative;
-	padding: 10px;
-	background: rgba(0, 0, 0, .04);
-	border-radius: 5px;
-}
-
-.speech-bubble:after {
-	content: '';
-	position: absolute;
-	top: 100%;
-	right: 30px;
-	border: 13px solid transparent;
-	border-top-color: rgba(0, 0, 0, .04);
-}
-
-.learn-bar > .learn {
-	position: absolute;
-	width: 272px;
-	top: 8px;
-	left: -300px;
-	padding: 10px;
-	border-radius: 5px;
-	background-color: rgba(255, 255, 255, .6);
-	-webkit-transition-property: left;
-	transition-property: left;
-	-webkit-transition-duration: 500ms;
-	transition-duration: 500ms;
-}
-
-@media (min-width: 899px) {
-	.learn-bar {
-		width: auto;
-		margin: 0 0 0 300px;
-	}
-
-	.learn-bar > .learn {
-		left: 8px;
-	}
-
-	.learn-bar #todoapp {
-		width: 550px;
-		margin: 130px auto 40px auto;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.js b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.js
deleted file mode 100644
index 099da60..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.js
+++ /dev/null
@@ -1,209 +0,0 @@
-(function () {
-	'use strict';
-
-	// Underscore's Template Module
-	// Courtesy of underscorejs.org
-	var _ = (function (_) {
-		_.defaults = function (object) {
-			if (!object) {
-				return object;
-			}
-			for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
-				var iterable = arguments[argsIndex];
-				if (iterable) {
-					for (var key in iterable) {
-						if (object[key] == null) {
-							object[key] = iterable[key];
-						}
-					}
-				}
-			}
-			return object;
-		}
-
-		// By default, Underscore uses ERB-style template delimiters, change the
-		// following template settings to use alternative delimiters.
-		_.templateSettings = {
-			evaluate    : /<%([\s\S]+?)%>/g,
-			interpolate : /<%=([\s\S]+?)%>/g,
-			escape      : /<%-([\s\S]+?)%>/g
-		};
-
-		// When customizing `templateSettings`, if you don't want to define an
-		// interpolation, evaluation or escaping regex, we need one that is
-		// guaranteed not to match.
-		var noMatch = /(.)^/;
-
-		// Certain characters need to be escaped so that they can be put into a
-		// string literal.
-		var escapes = {
-			"'":      "'",
-			'\\':     '\\',
-			'\r':     'r',
-			'\n':     'n',
-			'\t':     't',
-			'\u2028': 'u2028',
-			'\u2029': 'u2029'
-		};
-
-		var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
-
-		// JavaScript micro-templating, similar to John Resig's implementation.
-		// Underscore templating handles arbitrary delimiters, preserves whitespace,
-		// and correctly escapes quotes within interpolated code.
-		_.template = function(text, data, settings) {
-			var render;
-			settings = _.defaults({}, settings, _.templateSettings);
-
-			// Combine delimiters into one regular expression via alternation.
-			var matcher = new RegExp([
-				(settings.escape || noMatch).source,
-				(settings.interpolate || noMatch).source,
-				(settings.evaluate || noMatch).source
-			].join('|') + '|$', 'g');
-
-			// Compile the template source, escaping string literals appropriately.
-			var index = 0;
-			var source = "__p+='";
-			text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
-				source += text.slice(index, offset)
-					.replace(escaper, function(match) { return '\\' + escapes[match]; });
-
-				if (escape) {
-					source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
-				}
-				if (interpolate) {
-					source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
-				}
-				if (evaluate) {
-					source += "';\n" + evaluate + "\n__p+='";
-				}
-				index = offset + match.length;
-				return match;
-			});
-			source += "';\n";
-
-			// If a variable is not specified, place data values in local scope.
-			if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
-
-			source = "var __t,__p='',__j=Array.prototype.join," +
-				"print=function(){__p+=__j.call(arguments,'');};\n" +
-				source + "return __p;\n";
-
-			try {
-				render = new Function(settings.variable || 'obj', '_', source);
-			} catch (e) {
-				e.source = source;
-				throw e;
-			}
-
-			if (data) return render(data, _);
-			var template = function(data) {
-				return render.call(this, data, _);
-			};
-
-			// Provide the compiled function source as a convenience for precompilation.
-			template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
-
-			return template;
-		};
-
-		return _;
-	})({});
-
-	if (location.hostname === 'todomvc.com') {
-		window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
-	}
-
-	function redirect() {
-		if (location.hostname === 'tastejs.github.io') {
-			location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
-		}
-	}
-
-	function findRoot() {
-		var base;
-
-		[/labs/, /\w*-examples/].forEach(function (href) {
-			var match = location.href.match(href);
-
-			if (!base && match) {
-				base = location.href.indexOf(match);
-			}
-		});
-
-		return location.href.substr(0, base);
-	}
-
-	function getFile(file, callback) {
-		if (!location.host) {
-			return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
-		}
-
-		var xhr = new XMLHttpRequest();
-
-		xhr.open('GET', findRoot() + file, true);
-		xhr.send();
-
-		xhr.onload = function () {
-			if (xhr.status === 200 && callback) {
-				callback(xhr.responseText);
-			}
-		};
-	}
-
-	function Learn(learnJSON, config) {
-		if (!(this instanceof Learn)) {
-			return new Learn(learnJSON, config);
-		}
-
-		var template, framework;
-
-		if (typeof learnJSON !== 'object') {
-			try {
-				learnJSON = JSON.parse(learnJSON);
-			} catch (e) {
-				return;
-			}
-		}
-
-		if (config) {
-			template = config.template;
-			framework = config.framework;
-		}
-
-		if (!template && learnJSON.templates) {
-			template = learnJSON.templates.todomvc;
-		}
-
-		if (!framework && document.querySelector('[data-framework]')) {
-			framework = document.querySelector('[data-framework]').getAttribute('data-framework');
-		}
-
-
-		if (template && learnJSON[framework]) {
-			this.frameworkJSON = learnJSON[framework];
-			this.template = template;
-
-			this.append();
-		}
-	}
-
-	Learn.prototype.append = function () {
-		var aside = document.createElement('aside');
-		aside.innerHTML = _.template(this.template, this.frameworkJSON);
-		aside.className = 'learn';
-
-		// Localize demo links
-		var demoLinks = aside.querySelectorAll('.demo-link');
-		Array.prototype.forEach.call(demoLinks, function (demoLink) {
-			demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
-		});
-
-		document.body.className = (document.body.className + ' learn-bar').trim();
-		document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
-	};
-
-	redirect();
-	getFile('learn.json', Learn);
-})();
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bg.png b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bg.png
deleted file mode 100644
index b2a7600..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bg.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bower.json
deleted file mode 100644
index cdc4a43..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bower.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "todomvc-common",
-  "version": "0.1.9"
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/readme.md b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/readme.md
deleted file mode 100644
index 566a64c..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/readme.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# todomvc-common
-
-> Bower component for some common utilities we use in every app
-
-
-## License
-
-MIT
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-input.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-input.html
deleted file mode 100755
index 5679be1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-input.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<link rel="import" href="../components/polymer/polymer.html">
-
-<polymer-element name="td-input" extends="input" on-keyup="{{keyupAction}}" on-keypress="{{keypressAction}}">
-	<script>
-		(function() {
-			var ENTER_KEY = 13;
-			var ESC_KEY = 27;
-			Polymer('td-input', {
-				keypressAction: function(e, detail, sender) {
-					// Listen for enter on keypress but esc on keyup, because
-					// IE doesn't fire keyup for enter.
-					if (e.keyCode === ENTER_KEY) {
-						this.fire('td-input-commit');
-					}
-				},
-				keyupAction: function(e, detail, sender) {
-					if (e.keyCode === ESC_KEY) {
-						this.fire('td-input-cancel');
-					}
-				}
-			});
-		})();
-	</script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.css b/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.css
deleted file mode 100755
index c3768aef..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.css
+++ /dev/null
@@ -1,161 +0,0 @@
-/* base.css overrides */
-@host {
-	.editing {
-		border-bottom: none;
-		padding: 0;
-	}
-}
-
-button {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background-color: transparent;
-	background-image: none;
-	font-size: 100%;
-	vertical-align: baseline;
-	font-family: inherit;
-	color: inherit;
-	-webkit-appearance: none;
-	/*-moz-appearance: none;*/
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-
-.edit {
-	position: relative;
-	margin: 0;
-	width: 100%;
-	font-size: 24px;
-	font-family: inherit;
-	line-height: 1.4em;
-	border: 0;
-	outline: none;
-	color: inherit;
-	padding: 6px;
-	border: 1px solid #999;
-	box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	box-sizing: border-box;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-.edit {
-	width: 506px;
-	padding: 13px 17px 12px 17px;
-	margin: 0 0 0 43px;
-}
-
-.toggle {
-	text-align: center;
-	width: 40px;
-	/* auto, since non-WebKit browsers doesn't support input styling */
-	height: auto;
-	position: absolute;
-	top: 0;
-	bottom: 0;
-	margin: auto 0;
-	border: none; /* Mobile Safari */
-	-webkit-appearance: none;
-	/*-moz-appearance: none;*/
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-.toggle:after {
-	content: '✔';
-	line-height: 43px; /* 40 + a couple of pixels visual adjustment */
-	font-size: 20px;
-	color: #d9d9d9;
-	text-shadow: 0 -1px 0 #bfbfbf;
-}
-
-.toggle:checked:after {
-	color: #85ada7;
-	text-shadow: 0 1px 0 #669991;
-	bottom: 1px;
-	position: relative;
-}
-
-label {
-	word-break: break-word;
-	padding: 15px;
-	margin-left: 45px;
-	display: block;
-	line-height: 1.2;
-	-webkit-transition: color 0.4s;
-	-moz-transition: color 0.4s;
-	-ms-transition: color 0.4s;
-	-o-transition: color 0.4s;
-	transition: color 0.4s;
-}
-
-.completed label {
-	color: #a9a9a9;
-	text-decoration: line-through;
-}
-
-.destroy {
-	display: none;
-	position: absolute;
-	top: 0;
-	right: 10px;
-	bottom: 0;
-	width: 40px;
-	height: 40px;
-	margin: auto 0;
-	font-size: 22px;
-	color: #a88a8a;
-	-webkit-transition: all 0.2s;
-	-moz-transition: all 0.2s;
-	-ms-transition: all 0.2s;
-	-o-transition: all 0.2s;
-	transition: all 0.2s;
-}
-
-.destroy:hover {
-	text-shadow: 0 0 1px #000,
-				 0 0 10px rgba(199, 107, 107, 0.8);
-	-webkit-transform: scale(1.3);
-	-moz-transform: scale(1.3);
-	-ms-transform: scale(1.3);
-	-o-transform: scale(1.3);
-	transform: scale(1.3);
-}
-
-.destroy:after {
-	content: '✖';
-}
-
-.view:hover .destroy {
-	display: block;
-}
-
-/*
-	Hack to remove background from Mobile Safari.
-	Can't use it globally since it destroys checkboxes in Firefox and Opera
-*/
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-	.toggle {
-		background: none;
-    /* 
-      ShadowDOM Polyfill work around for webkit/blink bug 
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-	}
-
-	.toggle {
-		height: 40px;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.html
deleted file mode 100755
index 2cc13a3..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<link rel="import" href="../components/polymer/polymer.html">
-<link rel="import" href="td-input.html">
-
-<polymer-element name="td-item" extends="li" attributes="item editing" on-blur="{{commitAction}}">
-	<template>
-		<link rel="stylesheet" href="td-item.css">
-		<div class="view {{ {completed: item.completed, editing: editing} | tokenList }}" hidden?="{{editing}}" on-dblclick="{{editAction}}">
-			<input type="checkbox" class="toggle" checked="{{item.completed}}" on-click="{{itemChangeAction}}">
-			<label>{{item.title}}</label>
-			<button class="destroy" on-click="{{destroyAction}}"></button>
-		</div>
-		<input is="td-input" id="edit" class="edit" value="{{item.title}}" hidden?="{{!editing}}" on-td-input-commit="{{commitAction}}" on-td-input-cancel="{{cancelAction}}">
-	</template>
-	<script>
-		(function() {
-			Polymer('td-item', {
-				editing: false,
-				editAction: function() {
-					this.editing = true;
-					// schedule focus for the end of microtask, when the input will be visible
-					this.asyncMethod(function() {
-						this.$.edit.focus();
-					});
-				},
-				commitAction: function() {
-					if (this.editing) {
-						this.editing = false;
-						this.item.title = this.item.title.trim();
-						if (this.item.title === '') {
-							this.destroyAction();
-						}
-						this.fire('td-item-changed');
-					}
-				},
-				cancelAction: function() {
-					this.editing = false;
-				},
-				itemChangeAction: function() {
-					this.fire('td-item-changed');
-				},
-				destroyAction: function() {
-					this.fire('td-destroy-item', this.item);
-				}
-			});
-		})();
-	</script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-model.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-model.html
deleted file mode 100755
index 19f3d22..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-model.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<link rel="import" href="../components/polymer/polymer.html">
-
-<polymer-element name="td-model" attributes="filter items storageId">
-	<script>
-		Polymer('td-model', {
-			filtered: null,
-			completedCount: 0,
-			activeCount: 0,
-			allCompleted: false,
-			ready: function() {
-				this.asyncMethod(function() {
-					this.items = this.items || [];
-				});
-			},
-			filterChanged: function() {
-				this.filterItems();
-			},
-			itemsChanged: function() {
-				this.completedCount =
-					this.items.filter(this.filters.completed).length;
-				this.activeCount = this.items.length - this.completedCount;
-				this.allCompleted = this.completedCount && !this.activeCount;
-				this.filterItems();
-				if (this.storage) {
-					this.storage.value = this.items;
-					this.storage.save();
-				}
-			},
-			storageIdChanged: function() {
-				this.storage = document.querySelector('#' + this.storageId);
-				this.storage && (this.items = this.storage.value);
-			},
-			filterItems: function() {
-				var fn = this.filters[this.filter];
-				this.filtered = fn ? this.items.filter(fn) : this.items;
-			},
-			newItem: function(title) {
-				title = String(title).trim();
-				if (title) {
-					var item = {
-						title: title,
-						completed: false
-					};
-					this.items.push(item);
-					this.itemsChanged();
-				}
-			},
-			destroyItem: function(item) {
-				var i = this.items.indexOf(item);
-				if (i >= 0) {
-					this.items.splice(i, 1);
-				}
-				this.itemsChanged();
-			},
-			clearItems: function(){
-				this.items = this.items.filter(this.filters.active);
-			},
-			setItemsCompleted: function(completed) {
-				this.items.forEach(function(item) {
-					item.completed = completed;
-				});
-				this.itemsChanged();
-			},
-			filters: {
-				active: function(item) {
-					return !item.completed;
-				},
-				completed: function(item) {
-					return item.completed;
-				}
-			}
-	 });
-	</script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.css b/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.css
deleted file mode 100755
index 913d98b..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/* base.css overrides */
-
-@host { 
-	* { 
-		display: block;
-		position: relative;
-	}
-}
-
-button {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background: none;
-	font-size: 100%;
-	vertical-align: baseline;
-	font-family: inherit;
-	color: inherit;
-	-webkit-appearance: none;
-	/*-moz-appearance: none;*/
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-input::-webkit-input-placeholder {
-	font-style: italic;
-}
-
-input::-moz-placeholder {
-	font-style: italic;
-	color: #a9a9a9;
-}
-
-input:-ms-input-placeholder, #new-todo:-ms-input-placeholder {
-	font-style: italic;
-	color: #a9a9a9;
-}
-
-#todoapp {
-	background: #fff;
-	background: rgba(255, 255, 255, 0.9);
-	/*margin: 130px 0 40px 0;*/
-	margin: 0 0 40px 0;
-	border: 1px solid #ccc;
-	position: relative;
-	border-top-left-radius: 2px;
-	border-top-right-radius: 2px;
-	box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
-				0 25px 50px 0 rgba(0, 0, 0, 0.15);
-}
-
-#todoapp:before {
-	content: '';
-	border-left: 1px solid #f5d6d6;
-	border-right: 1px solid #f5d6d6;
-	width: 2px;
-	position: absolute;
-	top: 0;
-	left: 40px;
-	height: 100%;
-}
-
-#header {
-	padding-top: 15px;
-	border-radius: inherit;
-}
-
-#header:before {
-	content: '';
-	position: absolute;
-	top: 0;
-	right: 0;
-	left: 0;
-	height: 15px;
-	z-index: 2;
-	border-bottom: 1px solid #6c615c;
-	background: #8d7d77;
-	background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
-	background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
-	border-top-left-radius: 1px;
-	border-top-right-radius: 1px;
-}
-
-#new-todo,
-.edit {
-	position: relative;
-	margin: 0;
-	width: 100%;
-	font-size: 24px;
-	font-family: inherit;
-	line-height: 1.4em;
-	border: 0;
-	outline: none;
-	color: inherit;
-	padding: 6px;
-	border: 1px solid #999;
-	box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	box-sizing: border-box;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-#new-todo {
-	padding: 16px 16px 16px 60px;
-	border: none;
-	background: rgba(0, 0, 0, 0.02);
-	z-index: 2;
-	box-shadow: none;
-}
-
-#main {
-	position: relative;
-	z-index: 2;
-	border-top: 1px dotted #adadad;
-}
-
-label[for='toggle-all'] {
-	display: none;
-}
-
-#toggle-all {
-	position: absolute;
-	top: -42px;
-	left: -4px;
-	width: 40px;
-	text-align: center;
-	border: none; /* Mobile Safari */
-}
-
-#toggle-all:before {
-	content: '»';
-	font-size: 28px;
-	color: #d9d9d9;
-	padding: 0 25px 7px;
-}
-
-#toggle-all:checked:before {
-	color: #737373;
-}
-
-#todo-list {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-}
-
-#todo-list li {
-	position: relative;
-	font-size: 24px;
-	border-bottom: 1px dotted #ccc;
-}
-
-#todo-list li:last-child {
-	border-bottom: none;
-}
-
-#todo-list li.editing {
-	border-bottom: none;
-	padding: 0;
-}
-
-#footer {
-	color: #777;
-	padding: 0 15px;
-	position: absolute;
-	right: 0;
-	bottom: -31px;
-	left: 0;
-	height: 20px;
-	z-index: 1;
-	text-align: center;
-}
-
-#footer:before {
-	content: '';
-	position: absolute;
-	right: 0;
-	bottom: 31px;
-	left: 0;
-	height: 50px;
-	z-index: -1;
-	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
-				0 6px 0 -3px rgba(255, 255, 255, 0.8),
-				0 7px 1px -3px rgba(0, 0, 0, 0.3),
-				0 43px 0 -6px rgba(255, 255, 255, 0.8),
-				0 44px 2px -6px rgba(0, 0, 0, 0.2);
-}
-
-#todo-count {
-	float: left;
-	text-align: left;
-}
-
-#filters {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-	position: absolute;
-	right: 0;
-	left: 0;
-}
-
-#filters li {
-	display: inline;
-}
-
-#filters li a {
-	color: #83756f;
-	margin: 2px;
-	text-decoration: none;
-}
-
-#filters li.polymer-selected a {
-	font-weight: bold;
-}
-
-#clear-completed {
-	float: right;
-	position: relative;
-	line-height: 20px;
-	text-decoration: none;
-	background: rgba(0, 0, 0, 0.1);
-	font-size: 11px;
-	padding: 0 10px;
-	border-radius: 3px;
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
-}
-
-#clear-completed:hover {
-	background: rgba(0, 0, 0, 0.15);
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
-}
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-	#toggle-all {
-		background: none;
-    /* 
-      ShadowDOM Polyfill work around for webkit/blink bug 
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-	}
-
-	#toggle-all {
-		top: -56px;
-		left: -15px;
-		width: 65px;
-		height: 41px;
-		-webkit-transform: rotate(90deg);
-		transform: rotate(90deg);
-		-webkit-appearance: none;
-		appearance: none;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.html
deleted file mode 100755
index 2dc1ce5..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-<link rel="import" href="../components/polymer/polymer.html">
-<link rel="import" href="../components/polymer-selector/polymer-selector.html">
-<link rel="import" href="../components/flatiron-director/flatiron-director.html">
-<link rel="import" href="td-input.html">
-<link rel="import" href="td-item.html">
-
-<polymer-element name="td-todos" attributes="route modelId">
-	<template>
-		<link rel="stylesheet" href="td-todos.css">
-		<flatiron-director route="{{route}}"></flatiron-director>
-		<section id="todoapp">
-			<header id="header">
-				<input is="td-input" id="new-todo" placeholder="What needs to be done?" autofocus on-td-input-commit="{{addTodoAction}}" on-td-input-cancel="{{cancelAddTodoAction}}">
-			</header>
-			<section id="main" hidden?="{{model.items.length == 0}}">
-				<input id="toggle-all" type="checkbox" on-change="{{toggleAllCompletedAction}}" checked="{{model.allCompleted}}">
-				<label for="toggle-all">Mark all as complete</label>
-				<ul id="todo-list" on-td-item-changed="{{itemChangedAction}}" on-td-destroy-item="{{destroyItemAction}}">
-					<template repeat="{{model.filtered}}">
-						<li is="td-item" item="{{}}"></li>
-					</template>
-				</ul>
-			</section>
-			<footer id="footer" hidden?="{{model.items.length == 0}}">
-				<span id="todo-count"><strong>{{model.activeCount}}</strong> {{model.activeCount == 1 ? 'item' : 'items'}} left</span>
-				<polymer-selector id="filters" selected="{{route || 'all'}}">
-					<li name="all">
-						<a href="../#/">All</a>
-					</li>
-					<li name="active">
-						<a href="../#/active">Active</a>
-					</li>
-					<li name="completed">
-						<a href="../#/completed">Completed</a>
-					</li>
-				</polymer-selector>
-				<button hidden?="{{model.completedCount == 0}}" id="clear-completed" on-click="{{clearCompletedAction}}">Clear completed ({{model.completedCount}})</button>
-			</footer>
-		</section>
-	</template>
-
-	<script>
-		(function() {
-			var ENTER_KEY = 13;
-			var ESC_KEY = 27;
-			Polymer('td-todos', {
-				modelIdChanged: function() {
-					this.model = document.querySelector('#' + this.modelId);
-				},
-				routeChanged: function() {
-					this.model && (this.model.filter = this.route);
-				},
-				addTodoAction: function() {
-					this.model.newItem(this.$['new-todo'].value);
-					// when polyfilling Object.observe, make sure we update immediately
-					Platform.flush();
-					this.$['new-todo'].value = '';
-				},
-				cancelAddTodoAction: function() {
-					this.$['new-todo'].value = '';
-				},
-				itemChangedAction: function() {
-					this.model && this.model.itemsChanged();
-				},
-				destroyItemAction: function(e, detail) {
-					this.model.destroyItem(detail);
-				},
-				toggleAllCompletedAction: function(e, detail, sender) {
-					this.model.setItemsCompleted(sender.checked);
-				},
-				clearCompletedAction: function() {
-					this.model.clearItems();
-				}
-			});
-		})();
-	</script>
-
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/index.html b/samples/third_party/todomvc_performance/js_todomvc/index.html
deleted file mode 100755
index 8d21059..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!doctype html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8">
-		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-		<title>Polymer • TodoMVC</title>
-		<link rel="stylesheet" href="app/app.css">
-		<script src="components/platform/platform.js"></script>
-		<link rel="import" href="components/polymer-localstorage/polymer-localstorage.html">
-		<link rel="import" href="elements/td-model.html">
-		<link rel="import" href="elements/td-todos.html">
-    <script src="packages/browser_controller/perf_test_controller.js"></script>
-    <script type="application/javascript">
-      var startTime = new Date().getTime();
-
-      window.addEventListener('polymer-ready', function(e) {
-        var endTime = new Date().getTime();
-        var startupTime = endTime - startTime;
-        document.body.innerHTML = 'The startup time is ' + startupTime + ' milliseconds.';
-        reportPerformanceTestDone();
-      });
-    </script>
-	</head>
-	<body>
-		<header>
-			<h1>todos</h1>
-		</header>
-		<polymer-localstorage id="storage" name="todos-polymer"></polymer-localstorage>
-		<td-model id="model" storageId="storage"></td-model>
-		<td-todos modelId="model"></td-todos>
-		<footer id="info">
-			<p>Double-click to edit a todo</p>
-			<p>Created by <a href="http://www.polymer-project.org">The Polymer Authors</a></p>
-			<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
-		</footer>
-	</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/pubspec.yaml b/samples/third_party/todomvc_performance/js_todomvc/pubspec.yaml
deleted file mode 100644
index 61ed39d..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/pubspec.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: js_todomvc
-description: A snapshot of https://github.com/Polymer/todomvc
-version: 0.00.1
-dependencies:
-  browser_controller: ">=0.00.2-dev <0.0.2"
-environment:
-  sdk: ">=1.2.0 <2.0.0"
diff --git a/samples/third_party/todomvc_performance/pubspec.yaml b/samples/third_party/todomvc_performance/pubspec.yaml
deleted file mode 100644
index 6bbc539..0000000
--- a/samples/third_party/todomvc_performance/pubspec.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: todomvc
-description: TodoMVC built with the polymer.dart package
-version: 0.15.0
-dependencies:
-  polymer: ">=0.10.0-pre.1 <0.11.0"
-  browser_controller: ">=0.00.2-dev <0.0.3"
-transformers:
-- polymer:
-    entry_points: web/startup-performance.html
-    minify: true
-dev_dependencies:
-  unittest: ">=0.10.0 <0.11.0"
-environment:
-  sdk: ">=1.2.0 <2.0.0"
diff --git a/samples/third_party/todomvc_performance/web/app/app.css b/samples/third_party/todomvc_performance/web/app/app.css
deleted file mode 100644
index 68a1468..0000000
--- a/samples/third_party/todomvc_performance/web/app/app.css
+++ /dev/null
@@ -1,206 +0,0 @@
-/* base.css overrides */
-
-html,
-body {
-  margin: 0;
-  padding: 0;
-}
-
-body {
-  font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
-  line-height: 1.4em;
-  background: #eaeaea url('bg.png');
-  color: #4d4d4d;
-  width: 550px;
-  margin: 0 auto;
-  -webkit-font-smoothing: antialiased;
-  -moz-font-smoothing: antialiased;
-  -ms-font-smoothing: antialiased;
-  -o-font-smoothing: antialiased;
-  font-smoothing: antialiased;
-}
-
-body > header {
-  padding-top: 22px;
-  margin-bottom: -5px;
-}
-
-h1 {
-  /*  position: absolute;
-  top: -120px;*/
-  width: 100%;
-  font-size: 70px;
-  font-weight: bold;
-  text-align: center;
-  color: #b3b3b3;
-  color: rgba(255, 255, 255, 0.3);
-  text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-  -webkit-text-rendering: optimizeLegibility;
-  -moz-text-rendering: optimizeLegibility;
-  -ms-text-rendering: optimizeLegibility;
-  -o-text-rendering: optimizeLegibility;
-  text-rendering: optimizeLegibility;
-}
-
-#info {
-  margin: 65px auto 0;
-  color: #a6a6a6;
-  font-size: 12px;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-  text-align: center;
-}
-
-#info a {
-  color: inherit;
-}
-
-.hidden{
-  display:none;
-}
-
-hr {
-  margin: 20px 0;
-  border: 0;
-  border-top: 1px dashed #C5C5C5;
-  border-bottom: 1px dashed #F7F7F7;
-}
-
-.learn a {
-  font-weight: normal;
-  text-decoration: none;
-  color: #b83f45;
-}
-
-.learn a:hover {
-  text-decoration: underline;
-  color: #787e7e;
-}
-
-.learn h3,
-.learn h4,
-.learn h5 {
-  margin: 10px 0;
-  font-weight: 500;
-  line-height: 1.2;
-  color: #000;
-}
-
-.learn h3 {
-  font-size: 24px;
-}
-
-.learn h4 {
-  font-size: 18px;
-}
-
-.learn h5 {
-  margin-bottom: 0;
-  font-size: 14px;
-}
-
-.learn ul {
-  padding: 0;
-  margin: 0 0 30px 25px;
-}
-
-.learn li {
-  line-height: 20px;
-}
-
-.learn p {
-  font-size: 15px;
-  font-weight: 300;
-  line-height: 1.3;
-  margin-top: 0;
-  margin-bottom: 0;
-}
-
-.quote {
-  border: none;
-  margin: 20px 0 60px 0;
-}
-
-.quote p {
-  font-style: italic;
-}
-
-.quote p:before {
-  content: '“';
-  font-size: 50px;
-  opacity: .15;
-  position: absolute;
-  top: -20px;
-  left: 3px;
-}
-
-.quote p:after {
-  content: '”';
-  font-size: 50px;
-  opacity: .15;
-  position: absolute;
-  bottom: -42px;
-  right: 3px;
-}
-
-.quote footer {
-  position: absolute;
-  bottom: -40px;
-  right: 0;
-}
-
-.quote footer img {
-  border-radius: 3px;
-}
-
-.quote footer a {
-  margin-left: 5px;
-  vertical-align: middle;
-}
-
-.speech-bubble {
-  position: relative;
-  padding: 10px;
-  background: rgba(0, 0, 0, .04);
-  border-radius: 5px;
-}
-
-.speech-bubble:after {
-  content: '';
-  position: absolute;
-  top: 100%;
-  right: 30px;
-  border: 13px solid transparent;
-  border-top-color: rgba(0, 0, 0, .04);
-}
-
-/**body*/.learn-bar > .learn {
-  position: absolute;
-  width: 272px;
-  top: 8px;
-  left: -300px;
-  padding: 10px;
-  border-radius: 5px;
-  background-color: rgba(255, 255, 255, .6);
-  transition-property: left;
-  transition-duration: 500ms;
-}
-
-
-/* IE doesn't support the hidden attribute */
-[hidden] {
-  display: none;
-}
-
-@media (min-width: 899px) {
-  /**body*/.learn-bar {
-    width: auto;
-    margin: 0 0 0 300px;
-  }
-  /**body*/.learn-bar > .learn {
-    left: 8px;
-  }
-  /**body*/.learn-bar #todoapp {
-    width: 550px;
-    margin: 130px auto 40px auto;
-  }
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/web/app/bg.png b/samples/third_party/todomvc_performance/web/app/bg.png
deleted file mode 100644
index b2a7600..0000000
--- a/samples/third_party/todomvc_performance/web/app/bg.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/todomvc_performance/web/elements/td_input.dart b/samples/third_party/todomvc_performance/web/elements/td_input.dart
deleted file mode 100644
index fc3211f..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_input.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-library todomvc.web.elements.td_input;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-@CustomTag('td-input')
-class TodoInput extends InputElement with Polymer, Observable {
-  factory TodoInput() => new Element.tag('input', 'td-input');
-  TodoInput.created() : super.created() {
-    polymerCreated();
-  }
-
-  keypressAction(e) {
-    // Listen for enter on keypress but esc on keyup, because
-    // IE doesn't fire keyup for enter.
-    if (e.keyCode == KeyCode.ENTER) {
-      e.preventDefault();
-      fire('td-input-commit');
-    }
-  }
-
-  keyupAction(e) {
-    if (e.keyCode == KeyCode.ESC) {
-      fire('td-input-cancel');
-    }
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_input.html b/samples/third_party/todomvc_performance/web/elements/td_input.html
deleted file mode 100644
index 3190dc8..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_input.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<polymer-element name="td-input" extends="input"
-    on-keyup="{{keyupAction}}" on-keypress="{{keypressAction}}">
-  <script type="application/dart" src="td_input.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/elements/td_item.css b/samples/third_party/todomvc_performance/web/elements/td_item.css
deleted file mode 100644
index 61feb6c..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_item.css
+++ /dev/null
@@ -1,161 +0,0 @@
-/* base.css overrides */
-@host {
-  .editing {
-    border-bottom: none;
-    padding: 0;
-  }
-}
-
-button {
-  margin: 0;
-  padding: 0;
-  border: 0;
-  background-color: transparent;
-  background-image: none;
-  font-size: 100%;
-  vertical-align: baseline;
-  font-family: inherit;
-  color: inherit;
-  -webkit-appearance: none;
-  /*-moz-appearance: none;*/
-  -ms-appearance: none;
-  -o-appearance: none;
-  appearance: none;
-}
-
-
-.edit {
-  position: relative;
-  margin: 0;
-  width: 100%;
-  font-size: 24px;
-  font-family: inherit;
-  line-height: 1.4em;
-  border: 0;
-  outline: none;
-  color: inherit;
-  padding: 6px;
-  border: 1px solid #999;
-  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  -ms-box-sizing: border-box;
-  -o-box-sizing: border-box;
-  box-sizing: border-box;
-  -webkit-font-smoothing: antialiased;
-  -moz-font-smoothing: antialiased;
-  -ms-font-smoothing: antialiased;
-  -o-font-smoothing: antialiased;
-  font-smoothing: antialiased;
-}
-
-.edit {
-  width: 506px;
-  padding: 13px 17px 12px 17px;
-  margin: 0 0 0 43px;
-}
-
-.toggle {
-  text-align: center;
-  width: 40px;
-  /* auto, since non-WebKit browsers doesn't support input styling */
-  height: auto;
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  margin: auto 0;
-  border: none; /* Mobile Safari */
-  -webkit-appearance: none;
-  /*-moz-appearance: none;*/
-  -ms-appearance: none;
-  -o-appearance: none;
-  appearance: none;
-}
-
-.toggle:after {
-  content: '✔';
-  line-height: 43px; /* 40 + a couple of pixels visual adjustment */
-  font-size: 20px;
-  color: #d9d9d9;
-  text-shadow: 0 -1px 0 #bfbfbf;
-}
-
-.toggle:checked:after {
-  color: #85ada7;
-  text-shadow: 0 1px 0 #669991;
-  bottom: 1px;
-  position: relative;
-}
-
-label {
-  word-break: break-word;
-  padding: 15px;
-  margin-left: 45px;
-  display: block;
-  line-height: 1.2;
-  -webkit-transition: color 0.4s;
-  -moz-transition: color 0.4s;
-  -ms-transition: color 0.4s;
-  -o-transition: color 0.4s;
-  transition: color 0.4s;
-}
-
-.completed label {
-  color: #a9a9a9;
-  text-decoration: line-through;
-}
-
-.destroy {
-  display: none;
-  position: absolute;
-  top: 0;
-  right: 10px;
-  bottom: 0;
-  width: 40px;
-  height: 40px;
-  margin: auto 0;
-  font-size: 22px;
-  color: #a88a8a;
-  -webkit-transition: all 0.2s;
-  -moz-transition: all 0.2s;
-  -ms-transition: all 0.2s;
-  -o-transition: all 0.2s;
-  transition: all 0.2s;
-}
-
-.destroy:hover {
-  text-shadow: 0 0 1px #000,
-         0 0 10px rgba(199, 107, 107, 0.8);
-  -webkit-transform: scale(1.3);
-  -moz-transform: scale(1.3);
-  -ms-transform: scale(1.3);
-  -o-transform: scale(1.3);
-  transform: scale(1.3);
-}
-
-.destroy:after {
-  content: '✖';
-}
-
-.view:hover .destroy {
-  display: block;
-}
-
-/*
-  Hack to remove background from Mobile Safari.
-  Can't use it globally since it destroys checkboxes in Firefox and Opera
-*/
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-  .toggle {
-    background: none;
-    /*
-      ShadowDOM Polyfill work around for webkit/blink bug
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-  }
-
-  .toggle {
-    height: 40px;
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_item.dart b/samples/third_party/todomvc_performance/web/elements/td_item.dart
deleted file mode 100644
index 8970fe5..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_item.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-library todomvc.web.elements.td_item;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-import 'td_model.dart';
-
-@CustomTag('td-item')
-class TodoItem extends LIElement with Polymer, Observable {
-  @published bool editing = false;
-  @published Todo item;
-
-  factory TodoItem() => new Element.tag('li', 'td-item');
-  TodoItem.created() : super.created() { polymerCreated(); }
-
-  editAction() {
-    editing = true;
-    // schedule focus for the end of microtask, when the input will be visible
-    async((_) => $['edit'].focus());
-  }
-
-  commitAction() {
-    if (editing) {
-      editing = false;
-      item.title = item.title.trim();
-      if (item.title == '') {
-        destroyAction();
-      }
-      fire('td-item-changed');
-    }
-  }
-
-  cancelAction() {
-    editing = false;
-  }
-
-  itemChangeAction() {
-    // TODO(jmesserly): asyncFire is needed because "click" fires before
-    // "item.checked" is updated on Firefox. Need to check Polymer.js.
-    asyncFire('td-item-changed');
-  }
-
-  destroyAction() {
-    fire('td-destroy-item', detail: item);
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_item.html b/samples/third_party/todomvc_performance/web/elements/td_item.html
deleted file mode 100644
index 8d5dd0d..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_item.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<link rel="import" href="td_input.html">
-<polymer-element name="td-item" extends="li" on-blur="{{commitAction}}">
-  <template>
-    <link rel="stylesheet" href="td_item.css">
-    <div class="view {{ {'completed': item.completed, 'editing': editing} }}"
-        hidden?="{{editing}}" on-dblclick="{{editAction}}">
-      <input type="checkbox" class="toggle" checked="{{item.completed}}"
-          on-click="{{itemChangeAction}}">
-      <label>{{item.title}}</label>
-      <button class="destroy" on-click="{{destroyAction}}"></button>
-    </div>
-    <input is="td-input" id="edit" class="edit" value="{{item.title}}"
-        hidden?="{{!editing}}" on-td-input-commit="{{commitAction}}"
-        on-td-input-cancel="{{cancelAction}}">
-  </template>
-  <script type="application/dart" src="td_item.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/elements/td_model.dart b/samples/third_party/todomvc_performance/web/elements/td_model.dart
deleted file mode 100644
index 40fe756..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_model.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-library todomvc.web.elements.td_model;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-import '../lib-elements/polymer_localstorage.dart';
-
-class Todo extends Observable {
-  @observable String title;
-  @observable bool completed = false;
-
-  Todo(this.title);
-
-  Todo.fromJson(Map json)
-      : title = json['title'], completed = json['completed'];
-
-  Map toJson() => { 'title': title, 'completed': completed };
-
-  String toString() => "$title (${completed ? '' : 'not '}done)";
-}
-
-@CustomTag('td-model')
-class TodoModel extends PolymerElement {
-  @published ObservableList<Todo> items;
-  @published Iterable<Todo> filtered;
-  @published String storageId;
-
-  @observable int completedCount = 0;
-  @observable int activeCount = 0;
-  @observable bool allCompleted = false;
-  @observable PolymerLocalStorage storage;
-  @observable String filter;
-  @observable String activeItemWord;
-
-  final filters = {
-    'active': (item) => !item.completed,
-    'completed': (item) => item.completed
-  };
-
-  factory TodoModel() => new Element.tag('td-model');
-  TodoModel.created() : super.created();
-
-  void ready() {
-    async((_) {
-      if (items == null) items = new ObservableList<Todo>();
-    });
-  }
-
-  void filterChanged() {
-    filterItems();
-  }
-
-  void itemsChanged() {
-    completedCount = items.where(filters['completed']).length;
-    activeCount = items.length - completedCount;
-    allCompleted = completedCount > 0 && activeCount == 0;
-
-    filterItems();
-    if (storage != null) {
-      storage.value = items;
-      storage.save();
-    }
-
-    // TODO(jmesserly): polymer_expressions lacks ternary operator.
-    activeItemWord = activeCount == 1 ? 'item' : 'items';
-  }
-
-  void storageIdChanged() {
-    storage = document.querySelector('#$storageId');
-    if (storage != null && storage.value != null) {
-      items = toObservable(storage.value.map((i) => new Todo.fromJson(i)));
-    }
-  }
-
-  void filterItems() {
-    var fn = filters[filter];
-    filtered = fn != null ? items.where(fn) : items;
-  }
-
-  void newItem(String title) {
-    title = title.trim();
-    if (title != '') {
-      items.add(new Todo(title));
-      itemsChanged();
-    }
-  }
-
-  void destroyItem(Todo item) {
-    if (items.remove(item)) itemsChanged();
-  }
-
-  void clearItems() {
-    items.removeWhere(filters['completed']);
-  }
-
-  void setItemsCompleted(bool completed) {
-    for (var item in items) {
-      item.completed = completed;
-    }
-    itemsChanged();
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_model.html b/samples/third_party/todomvc_performance/web/elements/td_model.html
deleted file mode 100644
index 7c83535..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_model.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<polymer-element name="td-model">
-  <script type="application/dart" src="td_model.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/elements/td_todos.css b/samples/third_party/todomvc_performance/web/elements/td_todos.css
deleted file mode 100644
index 4806384..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_todos.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/* base.css overrides */
-
-@host {
-  * {
-    display: block;
-    position: relative;
-  }
-}
-
-button {
-  margin: 0;
-  padding: 0;
-  border: 0;
-  background: none;
-  font-size: 100%;
-  vertical-align: baseline;
-  font-family: inherit;
-  color: inherit;
-  -webkit-appearance: none;
-  /*-moz-appearance: none;*/
-  -ms-appearance: none;
-  -o-appearance: none;
-  appearance: none;
-}
-
-input::-webkit-input-placeholder {
-  font-style: italic;
-}
-
-input::-moz-placeholder {
-  font-style: italic;
-  color: #a9a9a9;
-}
-
-input:-ms-input-placeholder, #new-todo:-ms-input-placeholder {
-  font-style: italic;
-  color: #a9a9a9;
-}
-
-#todoapp {
-  background: #fff;
-  background: rgba(255, 255, 255, 0.9);
-  /*margin: 130px 0 40px 0;*/
-  margin: 0 0 40px 0;
-  border: 1px solid #ccc;
-  position: relative;
-  border-top-left-radius: 2px;
-  border-top-right-radius: 2px;
-  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
-        0 25px 50px 0 rgba(0, 0, 0, 0.15);
-}
-
-#todoapp:before {
-  content: '';
-  border-left: 1px solid #f5d6d6;
-  border-right: 1px solid #f5d6d6;
-  width: 2px;
-  position: absolute;
-  top: 0;
-  left: 40px;
-  height: 100%;
-}
-
-#header {
-  padding-top: 15px;
-  border-radius: inherit;
-}
-
-#header:before {
-  content: '';
-  position: absolute;
-  top: 0;
-  right: 0;
-  left: 0;
-  height: 15px;
-  z-index: 2;
-  border-bottom: 1px solid #6c615c;
-  background: #8d7d77;
-  background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
-  background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
-  border-top-left-radius: 1px;
-  border-top-right-radius: 1px;
-}
-
-#new-todo,
-.edit {
-  position: relative;
-  margin: 0;
-  width: 100%;
-  font-size: 24px;
-  font-family: inherit;
-  line-height: 1.4em;
-  border: 0;
-  outline: none;
-  color: inherit;
-  padding: 6px;
-  border: 1px solid #999;
-  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  -ms-box-sizing: border-box;
-  -o-box-sizing: border-box;
-  box-sizing: border-box;
-  -webkit-font-smoothing: antialiased;
-  -moz-font-smoothing: antialiased;
-  -ms-font-smoothing: antialiased;
-  -o-font-smoothing: antialiased;
-  /* font-smoothing: antialiased; */
-}
-
-#new-todo {
-  padding: 16px 16px 16px 60px;
-  border: none;
-  background: rgba(0, 0, 0, 0.02);
-  z-index: 2;
-  box-shadow: none;
-}
-
-#main {
-  position: relative;
-  z-index: 2;
-  border-top: 1px dotted #adadad;
-}
-
-label[for='toggle-all'] {
-  display: none;
-}
-
-#toggle-all {
-  position: absolute;
-  top: -42px;
-  left: -4px;
-  width: 40px;
-  text-align: center;
-  border: none; /* Mobile Safari */
-}
-
-#toggle-all:before {
-  content: '»';
-  font-size: 28px;
-  color: #d9d9d9;
-  padding: 0 25px 7px;
-}
-
-#toggle-all:checked:before {
-  color: #737373;
-}
-
-#todo-list {
-  margin: 0;
-  padding: 0;
-  list-style: none;
-}
-
-#todo-list li {
-  position: relative;
-  font-size: 24px;
-  border-bottom: 1px dotted #ccc;
-}
-
-#todo-list li:last-child {
-  border-bottom: none;
-}
-
-#todo-list li.editing {
-  border-bottom: none;
-  padding: 0;
-}
-
-#footer {
-  color: #777;
-  padding: 0 15px;
-  position: absolute;
-  right: 0;
-  bottom: -31px;
-  left: 0;
-  height: 20px;
-  z-index: 1;
-  text-align: center;
-}
-
-#footer:before {
-  content: '';
-  position: absolute;
-  right: 0;
-  bottom: 31px;
-  left: 0;
-  height: 50px;
-  z-index: -1;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
-        0 6px 0 -3px rgba(255, 255, 255, 0.8),
-        0 7px 1px -3px rgba(0, 0, 0, 0.3),
-        0 43px 0 -6px rgba(255, 255, 255, 0.8),
-        0 44px 2px -6px rgba(0, 0, 0, 0.2);
-}
-
-#todo-count {
-  float: left;
-  text-align: left;
-}
-
-#filters {
-  margin: 0;
-  padding: 0;
-  list-style: none;
-  position: absolute;
-  right: 0;
-  left: 0;
-}
-
-#filters li {
-  display: inline;
-}
-
-#filters li a {
-  color: #83756f;
-  margin: 2px;
-  text-decoration: none;
-}
-
-#filters li.polymer-selected a {
-  font-weight: bold;
-}
-
-#clear-completed {
-  float: right;
-  position: relative;
-  line-height: 20px;
-  text-decoration: none;
-  background: rgba(0, 0, 0, 0.1);
-  font-size: 11px;
-  padding: 0 10px;
-  border-radius: 3px;
-  box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
-}
-
-#clear-completed:hover {
-  background: rgba(0, 0, 0, 0.15);
-  box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
-}
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-  #toggle-all {
-    background: none;
-    /*
-      ShadowDOM Polyfill work around for webkit/blink bug
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-  }
-
-  #toggle-all {
-    top: -56px;
-    left: -15px;
-    width: 65px;
-    height: 41px;
-    -webkit-transform: rotate(90deg);
-    transform: rotate(90deg);
-    -webkit-appearance: none;
-    appearance: none;
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_todos.dart b/samples/third_party/todomvc_performance/web/elements/td_todos.dart
deleted file mode 100644
index f0ac238..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_todos.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-library todomvc.web.elements.td_todos;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-import 'td_input.dart';
-import 'td_model.dart';
-
-@CustomTag('td-todos')
-class TodoList extends PolymerElement {
-  @published String modelId;
-
-  @observable TodoModel model;
-  @observable String activeRoute;
-
-  factory TodoList() => new Element.tag('td-todos');
-  TodoList.created() : super.created();
-
-  TodoInput get _newTodo => $['new-todo'];
-
-  void modelIdChanged() {
-    model = document.querySelector('#$modelId');
-  }
-
-  void routeAction(e, route) {
-    if (model != null) model.filter = route;
-
-    // TODO(jmesserly): polymer_expressions lacks boolean conversions.
-    activeRoute = (route != null && route != '') ? route : 'all';
-  }
-
-  void addTodoAction() {
-    model.newItem(_newTodo.value);
-    // when polyfilling Object.observe, make sure we update immediately
-    Observable.dirtyCheck();
-    _newTodo.value = '';
-  }
-
-  void cancelAddTodoAction() {
-    _newTodo.value = '';
-  }
-
-  void itemChangedAction() {
-    if (model != null) model.itemsChanged();
-  }
-
-  void destroyItemAction(e, detail) {
-    model.destroyItem(detail);
-  }
-
-  void toggleAllCompletedAction(e, detail, sender) {
-    model.setItemsCompleted(sender.checked);
-  }
-
-  void clearCompletedAction() {
-    model.clearItems();
-  }
-
-  // TODO(jmesserly): workaround for HTML Imports not setting correct baseURI
-  String get baseUri =>
-      declaration.element.ownerDocument == document ? '../' : '';
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_todos.html b/samples/third_party/todomvc_performance/web/elements/td_todos.html
deleted file mode 100644
index 4d84f60..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_todos.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<link rel="import" href="../lib-elements/polymer-selector.html">
-<link rel="import" href="../lib-elements/simple_router.html">
-<link rel="import" href="td_input.html">
-<link rel="import" href="td_item.html">
-
-<polymer-element name="td-todos">
-  <template>
-    <link rel="stylesheet" href="td_todos.css">
-    <simple-router on-route="{{routeAction}}"></simple-router>
-    <section id="todoapp">
-      <header id="header">
-        <input is="td-input" id="new-todo" placeholder="What needs to be done?"
-            autofocus on-td-input-commit="{{addTodoAction}}"
-            on-td-input-cancel="{{cancelAddTodoAction}}">
-      </header>
-      <section id="main" hidden?="{{model.items.length == 0}}">
-        <input id="toggle-all" type="checkbox"
-            on-change="{{toggleAllCompletedAction}}"
-            checked="{{model.allCompleted}}">
-        <label for="toggle-all">Mark all as complete</label>
-        <ul id="todo-list" on-td-item-changed="{{itemChangedAction}}"
-            on-td-destroy-item="{{destroyItemAction}}">
-          <template repeat="{{model.filtered}}">
-            <li is="td-item" item="{{}}"></li>
-          </template>
-        </ul>
-      </section>
-      <footer id="footer" hidden?="{{model.items.length == 0}}">
-        <span id="todo-count"><strong>{{model.activeCount}}</strong>
-            {{model.activeItemWord}} left</span>
-        <polymer-selector id="filters" selected="{{activeRoute}}">
-          <li label="all">
-            <a href="{{baseUri}}#/">All</a>
-          </li>
-          <li label="active">
-            <a href="{{baseUri}}#/active">Active</a>
-          </li>
-          <li label="completed">
-            <a href="{{baseUri}}#/completed">Completed</a>
-          </li>
-        </polymer-selector>
-        <button hidden?="{{model.completedCount == 0}}" id="clear-completed"
-            on-click="{{clearCompletedAction}}">Clear completed
-            ({{model.completedCount}})</button>
-      </footer>
-    </section>
-  </template>
-
-  <script type="application/dart" src="td_todos.dart"></script>
-
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selection.html b/samples/third_party/todomvc_performance/web/lib-elements/polymer-selection.html
deleted file mode 100644
index 609ced3..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selection.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
--->
-<!--
-/**
- * The polymer-selection element is used to manage selection state. It has no
- * visual appearance and is typically used in conjuneciton with another element.
- * For example, <a href="polymer-selector.html">polymer-selector</a>
- * use a polymer-selection to manage selection.
- *
- * To mark an item as selected, call the select(item) method on
- * polymer-selection. Notice that the item itself is an argument to this method.
- * The polymer-selection element manages selection state for any given set of
- * items. When an item is selected, the `polymer-select` event is fired.
- * The attribute "multi" indicates if multiple items can be selected at once.
- *
- * Example:
- *
- *     <polymer-element name="selection-example">
- *        <template>
- *          <style>
- *            ::-webkit-distributed(> .selected) {
- *              font-weight: bold;
- *              font-style: italic;
- *            }
- *          </style>
- *          <ul on-tap="{{itemTapAction}}">
- *            <content></content>
- *          </ul>
- *          <polymer-selection id="selection" multi on-polymer-select="{{selectAction}}"></polymer-selection>
- *        </template>
- *        <script>
- *          Polymer('selection-example', {
- *            itemTapAction: function(e) {
- *              this.$.selection.select(e.target);
- *            },
- *            selectAction: function(e, detail) {
- *              detail.item.classList.toggle('selected', detail.isSelected);
- *            }
- *          });
- *        </script>
- *     </polymer-element>
- *
- *     <selection-example>
- *       <li>Red</li>
- *       <li>Green</li>
- *       <li>Blue</li>
- *     </selection-example>
- *
- * @class polymer-selection
- */
- /**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- *
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
--->
-<polymer-element name="polymer-selection" attributes="multi">
-  <template>
-    <style>
-      :host {
-        display: none !important;
-      }
-    </style>
-  </template>
-  <script>
-    Polymer('polymer-selection', {
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      ready: function() {
-        this.clear();
-      },
-      clear: function() {
-        this.selection = [];
-      },
-      /**
-       * Retrieves the selected item(s).
-       * @method getSelection
-       * @returns Returns the selected item(s). If the multi property is true,
-       * getSelection will return an array, otherwise it will return
-       * the selected item or undefined if there is no selection.
-      */
-      getSelection: function() {
-        return this.multi ? this.selection : this.selection[0];
-      },
-      /**
-       * Indicates if a given item is selected.
-       * @method isSelected
-       * @param {any} item The item whose selection state should be checked.
-       * @returns Returns true if `item` is selected.
-      */
-      isSelected: function(item) {
-        return this.selection.indexOf(item) >= 0;
-      },
-      setItemSelected: function(item, isSelected) {
-        if (item !== undefined && item !== null) {
-          if (isSelected) {
-            this.selection.push(item);
-          } else {
-            var i = this.selection.indexOf(item);
-            if (i >= 0) {
-              this.selection.splice(i, 1);
-            }
-          }
-          this.fire("polymer-select", {isSelected: isSelected, item: item});
-        }
-      },
-      /**
-       * Set the selection state for a given `item`. If the multi property
-       * is true, then the selected state of `item` will be toggled; otherwise
-       * the `item` will be selected.
-       * @method select
-       * @param {any} item: The item to select.
-      */
-      select: function(item) {
-        if (this.multi) {
-          this.toggle(item);
-        } else if (this.getSelection() !== item) {
-          this.setItemSelected(this.getSelection(), false);
-          this.setItemSelected(item, true);
-        }
-      },
-      /**
-       * Toggles the selection state for `item`.
-       * @method toggle
-       * @param {any} item: The item to toggle.
-      */
-      toggle: function(item) {
-        this.setItemSelected(item, !this.isSelected(item));
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selector.html b/samples/third_party/todomvc_performance/web/lib-elements/polymer-selector.html
deleted file mode 100644
index 9fd5074..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selector.html
+++ /dev/null
@@ -1,353 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
-/**
- * polymer-selector is used to manage a list of elements that can be selected.
- * The attribute "selected" indicates which item element is being selected.
- * The attribute "multi" indicates if multiple items can be selected at once.
- * Tapping on the item element would fire "polymer-activate" event. Use
- * "polymer-select" event to listen for selection changes.
- *
- * Example:
- *
- *     <polymer-selector selected="0">
- *       <div>Item 1</div>
- *       <div>Item 2</div>
- *       <div>Item 3</div>
- *     </polymer-selector>
- *
- * polymer-selector is not styled.  So one needs to use "polymer-selected" CSS
- * class to style the selected element.
- *
- *     <style>
- *       .item.polymer-selected {
- *         background: #eee;
- *       }
- *     </style>
- *     ...
- *     <polymer-selector>
- *       <div class="item">Item 1</div>
- *       <div class="item">Item 2</div>
- *       <div class="item">Item 3</div>
- *     </polymer-selector>
- *
- * @class polymer-selector
- */
-/**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- *
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
-/**
- * Fired when an item element is tapped.
- *
- * @event polymer-activate
- * @param {Object} detail
- *   @param {Object} detail.item the item element
- */
--->
-<link rel="import" href="polymer-selection.html">
-
-<polymer-element name="polymer-selector"
-    attributes="selected multi valueattr selectedClass selectedProperty selectedItem selectedModel selectedIndex notap target itemsSelector activateEvent">
-  <template>
-    <polymer-selection id="selection" multi="{{multi}}" on-polymer-select="{{selectionSelect}}"></polymer-selection>
-    <content id="items" select="*"></content>
-  </template>
-  <script>
-    Polymer('polymer-selector', {
-      /**
-       * Gets or sets the selected element.  Default to use the index
-       * of the item element.
-       *
-       * If you want a specific attribute value of the element to be
-       * used instead of index, set "valueattr" to that attribute name.
-       *
-       * Example:
-       *
-       *     <polymer-selector valueattr="label" selected="foo">
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       * In multi-selection this should be an array of values.
-       *
-       * Example:
-       *
-       *     <polymer-selector id="selector" valueattr="label" multi>
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       *     this.$.selector.selected = ['foo', 'zot'];
-       *
-       * @attribute selected
-       * @type Object
-       * @default null
-       */
-      selected: null,
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      /**
-       * Specifies the attribute to be used for "selected" attribute.
-       *
-       * @attribute valueattr
-       * @type string
-       * @default 'name'
-       */
-      valueattr: 'name',
-      /**
-       * Specifies the CSS class to be used to add to the selected element.
-       *
-       * @attribute selectedClass
-       * @type string
-       * @default 'polymer-selected'
-       */
-      selectedClass: 'polymer-selected',
-      /**
-       * Specifies the property to be used to set on the selected element
-       * to indicate its active state.
-       *
-       * @attribute selectedProperty
-       * @type string
-       * @default 'active'
-       */
-      selectedProperty: 'active',
-      /**
-       * Returns the currently selected element. In multi-selection this returns
-       * an array of selected elements.
-       *
-       * @attribute selectedItem
-       * @type Object
-       * @default null
-       */
-      selectedItem: null,
-      /**
-       * In single selection, this returns the model associated with the
-       * selected element.
-       *
-       * @attribute selectedModel
-       * @type Object
-       * @default null
-       */
-      selectedModel: null,
-      /**
-       * In single selection, this returns the selected index.
-       *
-       * @attribute selectedIndex
-       * @type number
-       * @default -1
-       */
-      selectedIndex: -1,
-      /**
-       * The target element that contains items.  If this is not set
-       * polymer-selector is the container.
-       *
-       * @attribute target
-       * @type Object
-       * @default null
-       */
-      target: null,
-      /**
-       * This can be used to query nodes from the target node to be used for
-       * selection items.  Note this only works if the 'target' property is set.
-       *
-       * Example:
-       *
-       *     <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></polymer-selector>
-       *     <form id="myForm">
-       *       <label><input type="radio" name="color" value="red"> Red</label> <br>
-       *       <label><input type="radio" name="color" value="green"> Green</label> <br>
-       *       <label><input type="radio" name="color" value="blue"> Blue</label> <br>
-       *       <p>color = {{color}}</p>
-       *     </form>
-       *
-       * @attribute itemSelector
-       * @type string
-       * @default ''
-       */
-      itemsSelector: '',
-      /**
-       * The event that would be fired from the item element to indicate
-       * it is being selected.
-       *
-       * @attribute activateEvent
-       * @type string
-       * @default 'tap'
-       */
-      activateEvent: 'tap',
-      notap: false,
-      ready: function() {
-        this.activateListener = this.activateHandler.bind(this);
-        this.observer = new MutationObserver(this.updateSelected.bind(this));
-        if (!this.target) {
-          this.target = this;
-        }
-      },
-      get items() {
-        var nodes = this.target !== this ? (this.itemsSelector ?
-            this.target.querySelectorAll(this.itemsSelector) :
-                this.target.children) : this.$.items.getDistributedNodes();
-        return Array.prototype.filter.call(nodes || [], function(n) {
-          return n && n.localName !== 'template';
-        });
-      },
-      targetChanged: function(old) {
-        if (old) {
-          this.removeListener(old);
-          this.observer.disconnect();
-        }
-        if (this.target) {
-          this.addListener(this.target);
-          this.observer.observe(this.target, {childList: true});
-        }
-      },
-      addListener: function(node) {
-        node.addEventListener(this.activateEvent, this.activateListener);
-      },
-      removeListener: function(node) {
-        node.removeEventListener(this.activateEvent, this.activateListener);
-      },
-      get selection() {
-        return this.$.selection.getSelection();
-      },
-      selectedChanged: function() {
-        this.updateSelected();
-      },
-      updateSelected: function() {
-        this.validateSelected();
-        if (this.multi) {
-          this.clearSelection();
-          this.selected && this.selected.forEach(function(s) {
-            this.valueToSelection(s);
-          }, this);
-        } else {
-          this.valueToSelection(this.selected);
-        }
-      },
-      validateSelected: function() {
-        // convert to an array for multi-selection
-        if (this.multi && !Array.isArray(this.selected) &&
-            this.selected !== null && this.selected !== undefined) {
-          this.selected = [this.selected];
-        }
-      },
-      clearSelection: function() {
-        if (this.multi) {
-          this.selection.slice().forEach(function(s) {
-            this.$.selection.setItemSelected(s, false);
-          }, this);
-        } else {
-          this.$.selection.setItemSelected(this.selection, false);
-        }
-        this.selectedItem = null;
-        this.$.selection.clear();
-      },
-      valueToSelection: function(value) {
-        var item = (value === null || value === undefined) ?
-            null : this.items[this.valueToIndex(value)];
-        this.$.selection.select(item);
-      },
-      updateSelectedItem: function() {
-        this.selectedItem = this.selection;
-      },
-      selectedItemChanged: function() {
-        if (this.selectedItem) {
-          var t = this.selectedItem.templateInstance;
-          this.selectedModel = t ? t.model : undefined;
-        } else {
-          this.selectedModel = null;
-        }
-        this.selectedIndex = this.selectedItem ?
-            parseInt(this.valueToIndex(this.selected)) : -1;
-      },
-      valueToIndex: function(value) {
-        // find an item with value == value and return it's index
-        for (var i=0, items=this.items, c; (c=items[i]); i++) {
-          if (this.valueForNode(c) == value) {
-            return i;
-          }
-        }
-        // if no item found, the value itself is probably the index
-        return value;
-      },
-      valueForNode: function(node) {
-        return node[this.valueattr] || node.getAttribute(this.valueattr);
-      },
-      // events fired from <polymer-selection> object
-      selectionSelect: function(e, detail) {
-        this.updateSelectedItem();
-        if (detail.item) {
-          this.applySelection(detail.item, detail.isSelected)
-        }
-      },
-      applySelection: function(item, isSelected) {
-        if (this.selectedClass) {
-          item.classList.toggle(this.selectedClass, isSelected);
-        }
-        if (this.selectedProperty) {
-          item[this.selectedProperty] = isSelected;
-        }
-      },
-      // event fired from host
-      activateHandler: function(e) {
-        if (!this.notap) {
-          var i = this.findDistributedTarget(e.target, this.items);
-          if (i >= 0) {
-            var item = this.items[i];
-            var s = this.valueForNode(item) || i;
-            if (this.multi) {
-              if (this.selected) {
-                this.addRemoveSelected(s);
-              } else {
-                this.selected = [s];
-              }
-            } else {
-              this.selected = s;
-            }
-            this.asyncFire('polymer-activate', {item: item});
-          }
-        }
-      },
-      addRemoveSelected: function(value) {
-        var i = this.selected.indexOf(value);
-        if (i >= 0) {
-          this.selected.splice(i, 1);
-        } else {
-          this.selected.push(value);
-        }
-        this.valueToSelection(value);
-      },
-      findDistributedTarget: function(target, nodes) {
-        // find first ancestor of target (including itself) that
-        // is in nodes, if any
-        while (target && target != this) {
-          var i = Array.prototype.indexOf.call(nodes, target);
-          if (i >= 0) {
-            return i;
-          }
-          target = target.parentNode;
-        }
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.dart b/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.dart
deleted file mode 100644
index 218aac4..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 The Polymer 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 todomvc.web.lib_elements.polymer_localstorage;
-
-import 'dart:convert' show JSON;
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-// TODO(jmesserly): replace with interop to <polymer-localstorage>.
-@CustomTag('polymer-localstorage')
-class PolymerLocalStorage extends PolymerElement {
-  @published String name;
-  @published var value;
-  @published bool useRaw = false;
-
-  factory PolymerLocalStorage() => new Element.tag('polymer-localstorage');
-  PolymerLocalStorage.created() : super.created();
-
-  void ready() {
-    load();
-  }
-
-  void valueChanged() {
-    save();
-  }
-
-  void load() {
-    var s = window.localStorage[name];
-    if (s != null && !useRaw) {
-      value = JSON.decode(s);
-    } else {
-      value = s;
-    }
-  }
-
-  void save() {
-    window.localStorage[name] = useRaw ? value : JSON.encode(value);
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.html b/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.html
deleted file mode 100644
index 804d50a..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * polymer-localstorage provides access to localStorage.
- *
- * Example:
- *
- *     <polymer-localstorage name="my-app-storage" value="{{value}}">
- *     </polymer-localstorage>
- */
--->
-<polymer-element name="polymer-localstorage">
-  <template>
-    <style>
-      @host {
-        * {
-          display: none;
-        }
-      }
-    </style>
-  </template>
-  <script type="application/dart" src="polymer_localstorage.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.dart b/samples/third_party/todomvc_performance/web/lib-elements/simple_router.dart
deleted file mode 100644
index 1337a26..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 The Polymer 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 todomvc.web.lib_elements.simple_router;
-
-import 'dart:async';
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-// A very simple router for TodoMVC. Real app should use package:route, but it
-// does not currently support Shadow DOM.
-@CustomTag('simple-router')
-class SimpleRouter extends PolymerElement {
-  @published String route = '';
-
-  StreamSubscription _sub;
-
-  factory SimpleRouter() => new Element.tag('simple-router');
-  SimpleRouter.created() : super.created();
-
-  attached() {
-    super.attached();
-    _sub = windowLocation.changes.listen((_) {
-      var hash = window.location.hash;
-      if (hash.startsWith('#/')) hash = hash.substring(2);
-      // TODO(jmesserly): empty string is not triggering a call to TodoList
-      // routeChanged after deployment. Use 'all' as a workaround.
-      if (hash == '') hash = 'all';
-      route = hash;
-    });
-  }
-
-  detached() {
-    super.detached();
-    _sub.cancel();
-  }
-
-  routeChanged() {
-    fire('route', detail: route);
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.html b/samples/third_party/todomvc_performance/web/lib-elements/simple_router.html
deleted file mode 100644
index 909036e..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<polymer-element name="simple-router">
-  <script type="application/dart" src="simple_router.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/performance.dart b/samples/third_party/todomvc_performance/web/performance.dart
deleted file mode 100644
index 93ce1dc..0000000
--- a/samples/third_party/todomvc_performance/web/performance.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2014, 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 todomvc_performance;
-
-import 'dart:async';
-import 'dart:html';
-import 'dart:js' as js;
-import 'package:polymer/polymer.dart';
-import 'package:web_components/polyfill.dart';
-import 'elements/td_model.dart';
-
-/**
- * This test determines how fast the TodoMVC app has loaded.
- */
-main() {
-  initPolymer();
-  Polymer.onReady.then((_) {
-    var endInitTime = new DateTime.now();
-    window.postMessage(endInitTime.millisecondsSinceEpoch, '*');
-  });
-}
diff --git a/samples/third_party/todomvc_performance/web/startup-performance.html b/samples/third_party/todomvc_performance/web/startup-performance.html
deleted file mode 100644
index 7aeb547..0000000
--- a/samples/third_party/todomvc_performance/web/startup-performance.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!doctype html>
-
-<!--
-Copyright (c) 2014, 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.
--->	
-
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-
-    <script type="application/javascript">
-
-      // TODO(efortuna): Revisit in a bit -- should we use
-      // performance.timing.navigationStart?
-      // navigationStart may be a bit noisy. Re-evaluate after we have more
-      // data. Note: performance.timing.domLoading would be nice, but
-      // performance.timing seems to be null on Safari 7.0.2. (Issue 17923)
-      var startTime = new Date().getTime();
-      function onReceive(e) {
-        // Listen for a timestamp signifying when app startup is complete.
-        var endTime = e.data;
-        var startupTime = endTime - startTime;
-        document.body.innerHTML = 'The startup time is ' + startupTime + 
-            ' milliseconds.';
-        reportPerformanceTestDone();
-      }
-      window.addEventListener('message', onReceive, true);
-    </script>
-
-    <script src="packages/browser_controller/perf_test_controller.js"></script>
-    <title> TodoMVC • Startup Performance </title>
-    <link rel="stylesheet" href="app/app.css">
-    <link rel="import" href="packages/polymer/polymer.html">
-    <link rel="import" href="lib-elements/polymer_localstorage.html">
-    <link rel="import" href="elements/td_model.html">
-    <link rel="import" href="elements/td_todos.html">
-  </head>
-  <body>
-    <header>
-      <h1>todos</h1>
-    </header>
-    <polymer-localstorage id="storage" name="todos-polymer">
-    </polymer-localstorage>
-    <td-model id="model" storageId="storage"></td-model>
-    <td-todos modelId="model"></td-todos>
-    <script type="application/dart" src="performance.dart"></script> 
-    <footer id="info">
-      <p>Double-click to edit a todo</p>
-      <p>Created by <a href="https://www.dartlang.org/polymer-dart/">
-          The Polymer.dart Authors</a></p>
-      <p>This example was built using a pre-alpha version of Polymer.dart.</p>
-      <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
-    </footer>
-  </body>
-</html>
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
index ac8b537..79931ba 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -20,6 +20,21 @@
   static Isolate get current => _currentIsolateCache;
 
   @patch
+  static Future<Uri> get packageRoot {
+    throw new UnsupportedError("Isolate.packageRoot");
+  }
+
+  @patch
+  static Future<Uri> get packageConfig {
+    throw new UnsupportedError("Isolate.packageConfig");
+  }
+
+  @patch
+  static Future<Uri> resolvePackageUri(Uri packageUri) {
+    throw new UnsupportedError("Isolate.resolvePackageUri");
+  }
+
+  @patch
   static Future<Isolate> spawn(void entryPoint(message), var message,
                                {bool paused: false, bool errorsAreFatal,
                                 SendPort onExit, SendPort onError}) {
@@ -66,9 +81,14 @@
        bool errorsAreFatal,
        bool checked,
        Map<String, String> environment,
-       Uri packageRoot}) {
+       Uri packageRoot,
+       Uri packageConfig,
+       bool automaticPackageResolution: false}) {
     if (environment != null) throw new UnimplementedError("environment");
     if (packageRoot != null) throw new UnimplementedError("packageRoot");
+    if (packageConfig != null) throw new UnimplementedError("packageConfig");
+    // TODO(lrn): Figure out how to handle the automaticPackageResolution
+    // parameter.
     bool forcePause = (errorsAreFatal != null) ||
                       (onExit != null) ||
                       (onError != null);
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index bcc2019..48f968f 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -317,6 +317,31 @@
   }
 
   /**
+   * Returns the result of the first future in [futures] to complete.
+   *
+   * The returned future is completed with the result of the first
+   * future in [futures] to report that it is complete.
+   * The results of all the other futures are discarded.
+   *
+   * If [futures] is empty, or if none of its futures complete,
+   * the returned future never completes.
+   */
+  static Future/*<T>*/ any/*<T>*/(Iterable<Future/*<T>*/> futures) {
+    var completer = new Completer.sync();
+    var onValue = (value) {
+      if (!completer.isCompleted) completer.complete(value);
+    };
+    var onError = (error, stack) {
+      if (!completer.isCompleted) completer.completeError(error, stack);
+    };
+    for (var future in futures) {
+      future.then(onValue, onError: onError);
+    }
+    return completer.future;
+  }
+
+
+  /**
    * Perform an async operation for each element of the iterable, in turn.
    *
    * Runs [f] for each element in [input] in order, moving to the next element
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index e3f3aa4..c2b6c68 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -113,6 +113,47 @@
   }
 
   /**
+   * Create a stream from a group of futures.
+   *
+   * The stream reports the results of the futures on the stream in the order
+   * in which the futures complete.
+   *
+   * If some futures have completed before calling `Stream.fromFutures`,
+   * their result will be output on the created stream in some unspecified
+   * order.
+   *
+   * When all futures have completed, the stream is closed.
+   *
+   * If no future is passed, the stream closes as soon as possible.
+   */
+  factory Stream.fromFutures(Iterable<Future<T>> futures) {
+    var controller = new StreamController<T>(sync: true);
+    int count = 0;
+    var onValue = (value) {
+      if (!controller.isClosed) {
+        controller._add(value);
+        if (--count == 0) controller._closeUnchecked();
+      }
+    };
+    var onError = (error, stack) {
+      if (!controller.isClosed) {
+        controller._addError(error, stack);
+        if (--count == 0) controller._closeUnchecked();
+      }
+    };
+    // The futures are already running, so start listening to them immediately
+    // (instead of waiting for the stream to be listened on).
+    // If we wait, we might not catch errors in the futures in time.
+    for (var future in futures) {
+      count++;
+      future.then(onValue, onError: onError);
+    }
+    // Use schedule microtask since controller is sync.
+    if (count == 0) scheduleMicrotask(controller.close);
+    return controller.stream;
+  }
+
+  /**
    * Creates a single-subscription stream that gets its data from [data].
    *
    * The iterable is iterated when the stream receives a listener, and stops
diff --git a/sdk/lib/core/annotations.dart b/sdk/lib/core/annotations.dart
index 5ceed34..6a596c6 100644
--- a/sdk/lib/core/annotations.dart
+++ b/sdk/lib/core/annotations.dart
@@ -113,26 +113,37 @@
 }
 
 /**
- * The annotation `@proxy` marks a class as implementing interfaces and members
- * dynamically through `noSuchMethod`.
+ * The annotation `@proxy` marks a class as implementing members dynamically
+ * through `noSuchMethod`.
  *
  * The annotation applies to any class. It is inherited by subclasses from both
  * superclass and interfaces.
  *
  * If a class is annotated with `@proxy`, or it implements any class that is
- * annotated, then the class is considered to implement any interface and
- * any member with regard to static type analysis. As such, it is not a static
- * type warning to assign the object to a variable of any type, and it is not
- * a static type warning to access any member of the object.
+ * annotated, then the class is considered to implement any member with regard
+ * to static type analysis.
+ * As such, it is not a static type warning to access any member of the object
+ * which is not implemented by the class, or to call a method with a different
+ * number of parameters than it is declared with.
  *
- * This only applies to static type warnings. The runtime type of the object
- * is unaffected. It is not considered to implement any special interfaces at
- * runtime, so assigning it to a typed variable may fail in checked mode, and
- * testing it with the `is` operator will not work for any type except the
- * ones it actually implements.
+ * The annotation does not change which classes the annotated class implements,
+ * and does not prevent static warnings for assigning an object to a variable
+ * with a static type not implemented by the object.
  *
- * Tools that understand `@proxy` should tell the user if a class using `@proxy`
- * does not override the `noSuchMethod` declared on [Object].
+ * The suppression of warnings only affect static type warnings about
+ * member access.
+ * The runtime type of the object is unaffected.
+ * It is not considered to implement any special interfaces,
+ * so assigning it to a typed variable may fail in checked mode,
+ * and testing it with the `is` operator
+ * will only return true for types it actually implements or extends.
+ * Accessing a member which isn't implemented by the classs
+ * will cause the `noSuchMethod` method to be called normally,
+ * the `@proxy` annotation merely states the intent to handle (some of) those
+ * `noSuchMethod` calls gracefully.
+ *
+ * A class that marked as `@proxy` should override the `noSuchMethod`
+ * declared on [Object].
  *
  * The intent of the `@proxy` notation is to create objects that implement a
  * type (or multiple types) that are not known at compile time. If the types
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 883ae88..2e82f34 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -17688,10 +17688,17 @@
   factory HashChangeEvent(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
-    var event = document._createEvent("HashChangeEvent");
-    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
-    return event;
+
+    var options = {
+      'canBubble' : canBubble,
+      'cancelable' : cancelable,
+      'oldURL': oldUrl,
+      'newURL': newUrl,
+    };
+    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)',
+        type, convertDartToNative_Dictionary(options));
   }
+
   // To suppress missing implicit constructor warnings.
   factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }
 
@@ -18029,7 +18036,9 @@
   @DomName('Document.body')
   BodyElement body;
 
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
   @DomName('Document.caretRangeFromPoint')
+  @Unstable()
   Range caretRangeFromPoint(int x, int y) {
     return _caretRangeFromPoint(x, y);
   }
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 0d1edad..6b85ade 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -19702,10 +19702,14 @@
   factory HashChangeEvent(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
+
+    // TODO(alanknight): This is required while we're on Dartium 39, but will need
+    // to look like dart2js with later versions when initHashChange is removed.
     var event = document._createEvent("HashChangeEvent");
     event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
   }
+
   // To suppress missing implicit constructor warnings.
   factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }
 
@@ -20099,7 +20103,9 @@
     _body = value;
   }
 
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
   @DomName('Document.caretRangeFromPoint')
+  @Unstable()
   Range caretRangeFromPoint(int x, int y) {
     return _caretRangeFromPoint(x, y);
   }
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 676e4a8..6b14ae2 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -713,6 +713,7 @@
           if (s[index] == " " ||
               s[index] == "\t" ||
               s[index] == "=" ||
+              s[index] == parameterSeparator ||
               s[index] == valueSeparator) break;
           index++;
         }
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 8d284d2..a0bfa67 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -127,6 +127,34 @@
   external static Isolate get current;
 
   /**
+   * Returns the package root of the current isolate, if any.
+   *
+   * If the isolate is using a [packageConfig] or the isolate has not been
+   * setup for package resolution, this getter returns `null`, otherwise it
+   * returns the package root - a directory that package URIs are resolved
+   * against.
+   */
+  external static Future<Uri> get packageRoot;
+
+  /**
+   * Returns the package root of the current isolate, if any.
+   *
+   * If the isolate is using a [packageRoot] or the isolate has not been
+   * setup for package resolution, this getter returns `null`, otherwise it
+   * returns the package config URI.
+   */
+  external static Future<Uri> get packageConfig;
+
+  /**
+   * Maps a package: URI to a non-package Uri.
+   *
+   * If there is no valid mapping from the package: URI in the current
+   * isolate, then this call returns `null`. Non-package: URIs are
+   * returned unmodified.
+   */
+  external static Future<Uri> resolvePackageUri(Uri packageUri);
+
+  /**
    * Creates and spawns an isolate that shares the same code as the current
    * isolate.
    *
@@ -222,6 +250,14 @@
    * resolved against this location, as by
    * `packageRoot.resolve("foo/bar.dart")`.
    *
+   * If the [packageConfig] parameter is provided, then it is used to find the
+   * location of a package resolution configuration file for the spawned
+   * isolate.
+   *
+   * If the [automaticPackageResolution] parameter is provided, then the
+   * location of the package sources in the spawned isolate is automatically
+   * determined.
+   *
    * The [environment] is a mapping from strings to strings which the
    * spawned isolate uses when looking up [String.fromEnvironment] values.
    * The system may add its own entries to environment as well.
@@ -244,7 +280,9 @@
        bool errorsAreFatal,
        bool checked,
        Map<String, String> environment,
-       Uri packageRoot});
+       Uri packageRoot,
+       Uri packageConfig,
+       bool automaticPackageResolution: false});
 
   /**
    * Requests the isolate to pause.
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index 9182442..7073e4d 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -58,7 +58,7 @@
   * Returns the lesser of two numbers.
   *
   * Returns NaN if either argument is NaN.
-  * The lesser of [:-0.0:] and [:0.0:] is [:-0.0:].
+  * The lesser of `-0.0` and `0.0` is `-0.0`.
   * If the arguments are otherwise equal (including int and doubles with the
   * same mathematical value) then it is unspecified which of the two arguments
   * is returned.
@@ -94,7 +94,7 @@
   * Returns the larger of two numbers.
   *
   * Returns NaN if either argument is NaN.
-  * The larger of [:-0.0:] and [:0.0:] is [:0.0:]. If the arguments are
+  * The larger of `-0.0` and `0.0` is `0.0`. If the arguments are
   * otherwise equal (including int and doubles with the same mathematical value)
   * then it is unspecified which of the two arguments is returned.
   */
@@ -135,7 +135,7 @@
  * Returns the angle between the positive x-axis and the vector ([b],[a]).
  * The result, in radians, is in the range -PI..PI.
  *
- * If [b] is positive, this is the same as [:atan(b/a):].
+ * If [b] is positive, this is the same as `atan(b/a)`.
  *
  * The result is negative when [a] is negative (including when [a] is the
  * double -0.0).
@@ -204,8 +204,8 @@
 /**
  * Converts [x] to a double and returns the tangent of the value.
  *
- * The tangent function is equivalent to [:sin(x)/cos(x):] and may be
- * infinite (positive or negative) when [:cos(x):] is equal to zero.
+ * The tangent function is equivalent to `sin(x)/cos(x)` and may be
+ * infinite (positive or negative) when `cos(x)` is equal to zero.
  * If [x] is not a finite number, the result is NaN.
  */
 external double tan(num x);
@@ -213,22 +213,22 @@
 /**
  * Converts [x] to a double and returns the arc cosine of the value.
  *
- * Returns a value in the range -PI..PI, or NaN if [x] is outside
+ * Returns a value in the range 0..PI, or NaN if [x] is outside
  * the range -1..1.
  */
 external double acos(num x);
 
 /**
  * Converts [x] to a double and returns the arc sine of the value.
- * 
- * Returns a value in the range -PI..PI, or  NaN if [x] is outside
+ *
+ * Returns a value in the range -PI/2..PI/2, or NaN if [x] is outside
  * the range -1..1.
  */
 external double asin(num x);
 
 /**
- * Converts [x] to a dobule and returns the arc tangent of the value.
- * 
+ * Converts [x] to a double and returns the arc tangent of the value.
+ *
  * Returns a value in the range -PI/2..PI/2, or NaN if [x] is NaN.
  */
 external double atan(num x);
@@ -243,14 +243,14 @@
 /**
  * Converts [x] to a double and returns the natural exponent, [E],
  * to the power [x].
- * 
+ *
  * Returns NaN if [x] is NaN.
  */
 external double exp(num x);
 
 /**
  * Converts [x] to a double and returns the natural logarithm of the value.
- * 
+ *
  * Returns negative infinity if [x] is equal to zero.
  * Returns NaN if [x] is NaN or less than zero.
  */
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index e9249bd..81419e9 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -14,6 +14,12 @@
 [ $runtime == vm || $runtime != vm ]
 # Tests that fail everywhere, including the analyzer.
 
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: Pass, Fail, OK # co19 issue 18
+
 # Super is now allowed in mixins and mixins may now extend a subclass of Object.
 Language/09_Mixins/09_Mixins_A01_t01: Skip # co19 issue 9.
 Language/09_Mixins/09_Mixins_A03_t01: Skip # co19 issue 9.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 19f53a4..a5781a6 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,12 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: MissingCompileTimeError # Please triage this failure
 Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError # compiler cancelled: cannot resolve type T
 Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError, OK # co19 issue 258
 Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t02: fail # Issue 13363
@@ -9626,7 +9620,6 @@
 Language/Statements/Continue/label_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
 Language/Statements/Continue/label_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
 Language/Types/Interface_Types/subtype_t39: RuntimeError # Please triage this failure.
-LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Crash # (lazy.method()): deferred access is not implemented
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
 LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 LibTest/core/Invocation/isGetter_A01_t01: RuntimeError # Please triage this failure.
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 465668d..ad67b18 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -36,11 +36,6 @@
 LayoutTests/fast/css/style-scoped/style-scoped-scoping-nodes-different-order_t01: RuntimeError # Dartium JSInterop failure
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: Fail # Please triage this failure.
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: Fail # Please triage this failure.
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: Fail # Please triage this failure.
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: Fail # Please triage this failure.
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: Fail # Please triage this failure.
 Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
 Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
 Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
@@ -81,7 +76,6 @@
 Language/Expressions/Instance_Creation/Const/abstract_class_t01: Fail # Issue 22007
 Language/Expressions/Instance_Creation/Const/abstract_class_t03: Fail # Issue 22007
 Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: RuntimeError # Please triage this failure.
-Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError # co19-roll r667: Please triage this failure
 Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure.
 Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
 Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
@@ -820,85 +814,18 @@
 LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
-LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError # Issue 13921
+LibTest/isolate/Isolate/spawn_A01_t03: Skip # co19-roll r667: Please triage this failure
+LibTest/isolate/Isolate/spawn_A01_t04: Skip # co19-roll r667: Please triage this failure
 LibTest/isolate/RawReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/RawReceivePort/handler_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/RawReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
 LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
 LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
 LibTest/isolate/ReceivePort/close_A02_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/drain_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/every_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/expand_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/firstWhere_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/firstWhere_A03_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/first_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/first_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/first_A02_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/fold_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/fold_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/forEach_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/isEmpty_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/join_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/join_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/lastWhere_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/lastWhere_A04_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/last_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/last_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/length_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/listen_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/map_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/pipe_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/reduce_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/reduce_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/reduce_A01_t03: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/singleWhere_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/single_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/single_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/skipWhile_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/skip_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/takeWhile_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/take_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/take_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/take_A01_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/toList_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/toSet_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/SendPort/send_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/SendPort/send_A01_t04: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t01: Fail # Issue 13921
 LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
 LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
 LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 0b6ea52..a11b526 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -81,6 +81,10 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip  # Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t02: Skip  # Timeout
 
+[ ($compiler == none || $compiler == precompiler) && $system == windows ]
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Slow
+LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Slow
+
 [ ($runtime == vm || $runtime == dart_precompiled) ]
 LibTest/isolate/Isolate/spawn_A02_t01: Skip # co19 issue 667
 LibTest/html/*: SkipByDesign # dart:html not supported on VM.
@@ -95,11 +99,6 @@
 
 [ ($runtime == vm || $runtime == dart_precompiled) ]
 # co19 update Sep 29, 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: MissingCompileTimeError # Please triage this failure
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: MissingCompileTimeError # Please triage this failure
 Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
 Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
 Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure
@@ -159,4 +158,4 @@
 Language/Metadata/*: Skip # Uses dart:mirrors
 
 [ $runtime == dart_precompiled ]
-LibTest/isolate/Isolate/spawnUri*: RuntimeError # Isolate.spawnUri
\ No newline at end of file
+LibTest/isolate/Isolate/spawnUri*: RuntimeError # Isolate.spawnUri
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 91b4ae2..d4f2f9f 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -29,5 +29,5 @@
       uriList.add(new Uri(scheme: 'dart', path: name));
     }
   });
-  asyncTest(() => analyze(uriList, WHITE_LIST));
+  asyncTest(() => analyze(uriList, WHITE_LIST, mode: AnalysisMode.ALL));
 }
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index ef6439d..41dc321 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -10,7 +10,8 @@
 import 'package:compiler/src/apiimpl.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/diagnostics/messages.dart' show
-    Message;
+    Message,
+    MessageKind;
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/source_file_provider.dart';
 import 'package:compiler/src/util/uri_extras.dart';
@@ -33,15 +34,16 @@
   bool hasErrors = false;
   bool lastWasWhitelisted = false;
 
-  Map<String, Map<String, int>> whiteListMap
-      = new Map<String, Map<String, int>>();
+  Map<String, Map<dynamic/*String|MessageKind*/, int>> whiteListMap
+      = new Map<String, Map<dynamic/*String|MessageKind*/, int>>();
 
-  CollectingDiagnosticHandler(Map<String, List<String>> whiteList,
-                              SourceFileProvider provider)
+  CollectingDiagnosticHandler(
+      Map<String, List/*<String|MessageKind>*/> whiteList,
+      SourceFileProvider provider)
       : super(provider) {
-    whiteList.forEach((String file, List<String> messageParts) {
-      var useMap = new Map<String,int>();
-      for (String messagePart in messageParts) {
+    whiteList.forEach((String file, List/*<String|MessageKind>*/ messageParts) {
+      var useMap = new Map<dynamic/*String|MessageKind*/, int>();
+      for (var messagePart in messageParts) {
         useMap[messagePart] = 0;
       }
       whiteListMap[file] = useMap;
@@ -57,7 +59,7 @@
   bool checkWhiteListUse() {
     bool allUsed = true;
     for (String file in whiteListMap.keys) {
-      for (String messagePart in whiteListMap[file].keys) {
+      for (var messagePart in whiteListMap[file].keys) {
         if (whiteListMap[file][messagePart] == 0) {
           print("Whitelisting '$messagePart' is unused in '$file'. "
                 "Remove the whitelisting from the whitelist map.");
@@ -70,7 +72,7 @@
 
   void reportWhiteListUse() {
     for (String file in whiteListMap.keys) {
-      for (String messagePart in whiteListMap[file].keys) {
+      for (var messagePart in whiteListMap[file].keys) {
         int useCount = whiteListMap[file][messagePart];
         print("Whitelisted message '$messagePart' suppressed $useCount "
               "time(s) in '$file'.");
@@ -78,15 +80,22 @@
     }
   }
 
-  bool checkWhiteList(Uri uri, String message) {
+  bool checkWhiteList(Uri uri, Message message, String text) {
     if (uri == null) {
       return false;
     }
     String path = uri.path;
     for (String file in whiteListMap.keys) {
       if (path.contains(file)) {
-        for (String messagePart in whiteListMap[file].keys) {
-          if (message.contains(messagePart)) {
+        for (var messagePart in whiteListMap[file].keys) {
+          bool found = false;
+          if (messagePart is String) {
+            found = text.contains(messagePart);
+          } else {
+            assert(messagePart is MessageKind);
+            found = message.kind == messagePart;
+          }
+          if (found) {
             whiteListMap[file][messagePart]++;
             return true;
           }
@@ -100,7 +109,7 @@
   void report(Message message, Uri uri, int begin, int end, String text,
               api.Diagnostic kind) {
     if (kind == api.Diagnostic.WARNING) {
-      if (checkWhiteList(uri, text)) {
+      if (checkWhiteList(uri, message, text)) {
         // Suppress whitelisted warnings.
         lastWasWhitelisted = true;
         return;
@@ -108,7 +117,7 @@
       hasWarnings = true;
     }
     if (kind == api.Diagnostic.HINT) {
-      if (checkWhiteList(uri, text)) {
+      if (checkWhiteList(uri, message, text)) {
         // Suppress whitelisted hints.
         lastWasWhitelisted = true;
         return;
@@ -116,7 +125,7 @@
       hasHint = true;
     }
     if (kind == api.Diagnostic.ERROR) {
-      if (checkWhiteList(uri, text)) {
+      if (checkWhiteList(uri, message, text)) {
         // Suppress whitelisted errors.
         lastWasWhitelisted = true;
         return;
@@ -134,11 +143,22 @@
 typedef bool CheckResults(CompilerImpl compiler,
                           CollectingDiagnosticHandler handler);
 
+enum AnalysisMode {
+  /// Analyze all declarations in all libraries in one go.
+  ALL,
+  /// Analyze all declarations in the main library.
+  MAIN,
+  /// Analyze all declarations in the given URIs one at a time. This mode can
+  /// handle URIs for parts (i.e. skips these).
+  URI,
+  /// Analyze all declarations reachable from the entry point.
+  TREE_SHAKING,
+}
+
 Future analyze(List<Uri> uriList,
-               Map<String, List<String>> whiteList,
-               {bool analyzeAll: true,
-                bool analyzeMain: false,
-                CheckResults checkResults}) {
+               Map<String, List/*<String|MessageKind>*/> whiteList,
+               {AnalysisMode mode: AnalysisMode.ALL,
+                CheckResults checkResults}) async {
   String testFileName =
       relativize(Uri.base, Platform.script, Platform.isWindows);
 
@@ -159,8 +179,17 @@
   var handler = new CollectingDiagnosticHandler(whiteList, provider);
   var options = <String>[Flags.analyzeOnly, '--categories=Client,Server',
       Flags.showPackageWarnings];
-  if (analyzeAll) options.add(Flags.analyzeAll);
-  if (analyzeMain) options.add(Flags.analyzeMain);
+  switch (mode) {
+    case AnalysisMode.URI:
+    case AnalysisMode.MAIN:
+      options.add(Flags.analyzeMain);
+      break;
+    case AnalysisMode.ALL:
+      options.add(Flags.analyzeAll);
+      break;
+    case AnalysisMode.TREE_SHAKING:
+      break;
+  }
   var compiler = new CompilerImpl(
       provider,
       null,
@@ -179,22 +208,25 @@
 ===
 """;
 
-  void onCompletion(_) {
-    bool result;
-    if (checkResults != null) {
-      result = checkResults(compiler, handler);
-    } else {
-      result = handler.checkResults();
+  if (mode == AnalysisMode.URI) {
+    for (Uri uri in uriList) {
+      await compiler.analyzeUri(uri);
     }
-    if (!result) {
-      print(MESSAGE);
-      exit(1);
-    }
-  }
-  if (analyzeAll || analyzeMain) {
+  } else if (mode != AnalysisMode.TREE_SHAKING) {
     compiler.librariesToAnalyzeWhenRun = uriList;
-    return compiler.run(null).then(onCompletion);
+    await compiler.run(null);
   } else {
-    return compiler.run(uriList.single).then(onCompletion);
+    await compiler.run(uriList.single);
+  }
+
+  bool result;
+  if (checkResults != null) {
+    result = checkResults(compiler, handler);
+  } else {
+    result = handler.checkResults();
+  }
+  if (!result) {
+    print(MESSAGE);
+    exit(1);
   }
 }
diff --git a/tests/compiler/dart2js/analyze_test_test.dart b/tests/compiler/dart2js/analyze_test_test.dart
new file mode 100644
index 0000000..f2565ac
--- /dev/null
+++ b/tests/compiler/dart2js/analyze_test_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2016, 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 dart2js.analyze_test.test;
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/apiimpl.dart' show
+    CompilerImpl;
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/diagnostics/messages.dart' show
+    MessageKind;
+import 'package:compiler/src/filenames.dart' show
+    nativeToUriPath;
+
+import 'analyze_helper.dart';
+import 'memory_compiler.dart';
+
+/**
+ * Map of white-listed warnings and errors.
+ *
+ * Use an identifiable suffix of the file uri as key. Use a fixed substring of
+ * the error/warning message in the list of white-listings for each file.
+ */
+// TODO(johnniwinther): Support canonical URIs as keys and message kinds as
+// values.
+const Map<String, List/*<String|MessageKind>*/> WHITE_LIST = const {
+  // Several tests import mirrors; any of these might trigger the warning.
+  ".dart": const [
+      MessageKind.IMPORT_EXPERIMENTAL_MIRRORS,
+  ],
+  "/test/src/util/": const [
+      "Library 'package:async/async.dart' doesn't export a "
+      "'ForkableStream' declaration.",
+  ],
+  "mirrors_test.dart": const [
+      MessageKind.INVALID_SYMBOL,
+      MessageKind.PRIVATE_IDENTIFIER,
+  ],
+};
+
+const List<String> SKIP_LIST = const <String>[
+  // Helper files:
+  "dart2js_batch2_run.dart",
+  "http_launch_data/",
+  "mirrors_helper.dart",
+  "path%20with%20spaces/",
+  "one_line_dart_program.dart",
+  "sourcemaps/invokes_test_file.dart",
+  "cps_ir/input/",
+  // No longer maintained:
+  "backend_dart/",
+  // Broken tests:
+  "http_test.dart",
+];
+
+main(List<String> arguments) {
+  bool verbose = arguments.contains('-v');
+
+  List<String> options = <String>[
+    Flags.analyzeOnly,
+    Flags.analyzeMain,
+    '--categories=Client,Server'];
+  if (verbose) {
+    options.add(Flags.verbose);
+  }
+  asyncTest(() async {
+    List<Uri> uriList = <Uri>[];
+    Directory dir =
+        new Directory.fromUri(Uri.base.resolve('tests/compiler/dart2js/'));
+    for (FileSystemEntity entity in dir.listSync(recursive: true)) {
+      if (entity is File && entity.path.endsWith('.dart')) {
+        Uri file = Uri.base.resolve(nativeToUriPath(entity.path));
+        if (!SKIP_LIST.any((skip) => file.path.contains(skip))) {
+          uriList.add(file);
+        }
+      }
+    }
+    await analyze(uriList, WHITE_LIST, mode: AnalysisMode.URI);
+  });
+}
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index 90fc59b2..8106a06 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -76,7 +76,7 @@
       // TODO(johnniwinther): Use [WHITE_LIST] again when
       // [Compiler.reportUnusedCode] is reenabled.
       const {}, // WHITE_LIST
-      analyzeAll: false,
+      mode: AnalysisMode.TREE_SHAKING,
       checkResults: checkResults));
 }
 
diff --git a/tests/compiler/dart2js/bad_output_io_test.dart b/tests/compiler/dart2js/bad_output_io_test.dart
index 7815b59..6f11981 100644
--- a/tests/compiler/dart2js/bad_output_io_test.dart
+++ b/tests/compiler/dart2js/bad_output_io_test.dart
@@ -4,7 +4,7 @@
 
 // Test that the compiler can handle imports when package root has not been set.
 
-library dart2js.test.missing_file;
+library dart2js.test.bad_output_io;
 
 import 'dart:io' show exit;
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/boolify_test.dart b/tests/compiler/dart2js/boolify_test.dart
index 6536386..7d2a7b9 100644
--- a/tests/compiler/dart2js/boolify_test.dart
+++ b/tests/compiler/dart2js/boolify_test.dart
@@ -2,7 +2,7 @@
 // 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 boolified_operator_test;
+library boolify_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index c3ee031..d88745d 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -4,7 +4,7 @@
 
 // Test for iterators on for [SubclassNode].
 
-library world_test;
+library class_set_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
@@ -12,6 +12,7 @@
 import 'package:compiler/src/elements/elements.dart'
        show Element, ClassElement;
 import 'package:compiler/src/universe/class_set.dart';
+import 'package:compiler/src/util/enumset.dart';
 import 'package:compiler/src/util/util.dart';
 import 'package:compiler/src/world.dart';
 
@@ -131,7 +132,8 @@
     }
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(G)).iterator;
+        world.getClassHierarchyNode(G),
+        ClassHierarchyNode.ALL).iterator;
     checkState(G, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -143,6 +145,7 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(G),
+        ClassHierarchyNode.ALL,
         includeRoot: false).iterator;
     checkState(G, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
@@ -151,7 +154,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(C)).iterator;
+        world.getClassHierarchyNode(C),
+        ClassHierarchyNode.ALL).iterator;
     checkState(C, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -171,7 +175,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(D)).iterator;
+        world.getClassHierarchyNode(D),
+        ClassHierarchyNode.ALL).iterator;
     checkState(D, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -182,7 +187,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(B)).iterator;
+        world.getClassHierarchyNode(B),
+        ClassHierarchyNode.ALL).iterator;
     checkState(B, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -197,6 +203,7 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(B),
+        ClassHierarchyNode.ALL,
         includeRoot: false).iterator;
     checkState(B, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
@@ -209,7 +216,9 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(B),
-        includeIndirectlyInstantiated: false).iterator;
+        new EnumSet<Instantiation>.fromValues(<Instantiation>[
+            Instantiation.DIRECTLY_INSTANTIATED,
+            Instantiation.UNINSTANTIATED])).iterator;
     checkState(B, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -220,7 +229,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(A)).iterator;
+        world.getClassHierarchyNode(A),
+        ClassHierarchyNode.ALL).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -250,6 +260,7 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(A),
+        ClassHierarchyNode.ALL,
         includeRoot: false).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
@@ -277,7 +288,9 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(A),
-        includeIndirectlyInstantiated: false).iterator;
+        new EnumSet<Instantiation>.fromValues(<Instantiation>[
+            Instantiation.DIRECTLY_INSTANTIATED,
+            Instantiation.UNINSTANTIATED])).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -304,8 +317,10 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(A),
-        includeRoot: false,
-        includeIndirectlyInstantiated: false).iterator;
+        new EnumSet<Instantiation>.fromValues(<Instantiation>[
+            Instantiation.DIRECTLY_INSTANTIATED,
+            Instantiation.UNINSTANTIATED]),
+        includeRoot: false).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -328,3 +343,4 @@
     Expect.isNull(iterator.current);
   }));
 }
+
diff --git a/tests/compiler/dart2js/cps_ir/README.md b/tests/compiler/dart2js/cps_ir/README.md
new file mode 100644
index 0000000..1106a72
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/README.md
@@ -0,0 +1,78 @@
+# CPS IR unit tests
+
+This folder contains unit tests of the CPS IR. These tests run the compiler with
+the cps IR and check for the output of a specific function (typically main).
+
+To make our lives easier, most files here are autogenerated. You should never
+have to edit a file under `expected/` or any file with an `AUTOGENERATED` header
+(including the `_test.dart` files).
+
+See instructions below to add or update tests.
+
+### Adding a new test
+
+Every test has 3 files: an input file, a test runner file, and an expectation
+file. The last two are auto-generated.  Here is how:
+
+* add a file under `input/` with a unique name, such as `foo_bar.dart`. Do not
+  include `_test` in the name of this file, otherwise the test framework will
+  think this test needs to be run directly in the vm and in a browser, that's
+  not our goal.
+
+* generate the corresponding test file, by running the `up_to_date_test.dart`
+  passing `update` as an argument:
+
+```bash
+dart tests/compiler/dart2js/cps_ir/up_to_date_test.dart update
+```
+
+  This will generate a file `foo_bar_test.dart` on this folder.
+
+* generate the expectations of the test file by running the generated test file
+  with `update` as an argument:
+
+```bash
+dart --package-root=out/ReleaseX64/packages tests/compiler/dart2js/cps_ir/foo_bar_test.dart update
+```
+
+  This will generate a file `expected/foo_bar.js` with the expected output.
+
+### Checking a method other than main
+
+By default, the test expectations will be generated to contain just the body of
+the main function. If you wish to check for a different element, include a
+comment at the top of the input test like this:
+```dart
+// Method to test: function(foo)
+```
+The trailing text should match the string representation of a compiler element.
+
+**Note**: this format will likely change in the future. We would like to have a
+canonical way to refer to elements that is independent of the internal compiler
+implementation, we also want a way to specify more than just one element, and a
+way to specify that an element has been tree-shaken.
+
+### Updating a single test expectation
+
+To update the expectations of a test, simply regenerate it by running the test
+file with `update` as an argument:
+
+```bash
+dart --package-root=out/ReleaseX64/packages tests/compiler/dart2js/cps_ir/foo_bar_test.dart update
+```
+
+This will override the file `expected/foo_bar.js` file with the new output.
+
+If a test fails because the expectations are out of date, you'll see this
+suggestion in the failure message too.
+
+### Updating all test expectations
+
+For convenience, we also provide a script to update all expectations at once.
+
+```bash
+dart --package-root=out/ReleaseX64/packages tests/compiler/dart2js/cps_ir/update_all.dart
+```
+
+It is equivalent to update each test individually. This script can be handy when
+making cross-cutting changes that affect the output of most tests.
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart
new file mode 100644
index 0000000..7e6129f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart
new file mode 100644
index 0000000..90e4293
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart
new file mode 100644
index 0000000..a170a0a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart
new file mode 100644
index 0000000..262f833
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart
new file mode 100644
index 0000000..5e081e0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart
new file mode 100644
index 0000000..32a89c7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart
new file mode 100644
index 0000000..7ec112f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart
new file mode 100644
index 0000000..41533c9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_17.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_17.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart
new file mode 100644
index 0000000..abda443
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_18.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_18.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart
new file mode 100644
index 0000000..03d2e0d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_19.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_19.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart
new file mode 100644
index 0000000..cbd95ce
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart
new file mode 100644
index 0000000..8421f29
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_20.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_20.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart
new file mode 100644
index 0000000..d65f1d2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_21.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_21.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart
new file mode 100644
index 0000000..b6fff18
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_22.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_22.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart
new file mode 100644
index 0000000..71083d4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_23.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_23.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart
new file mode 100644
index 0000000..ed56ade
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_24.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_24.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart
new file mode 100644
index 0000000..d3aa3a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_25.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_25.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart
new file mode 100644
index 0000000..348162f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_26.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_26.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart
new file mode 100644
index 0000000..545ed60
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_27.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_27.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart
new file mode 100644
index 0000000..4777d3d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_28.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_28.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart
new file mode 100644
index 0000000..82dfbed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart
new file mode 100644
index 0000000..3fa5714
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart
new file mode 100644
index 0000000..f254f71
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart
new file mode 100644
index 0000000..d90713c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart
new file mode 100644
index 0000000..1a35cbe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart
new file mode 100644
index 0000000..6069711
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart
new file mode 100644
index 0000000..082bb9b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart
new file mode 100644
index 0000000..49c5202
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart
new file mode 100644
index 0000000..4b2600c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart
new file mode 100644
index 0000000..e8f6b2c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart
new file mode 100644
index 0000000..5a5810c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart
new file mode 100644
index 0000000..a72d96b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart
new file mode 100644
index 0000000..9453955
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart
new file mode 100644
index 0000000..3fcdc5d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart
new file mode 100644
index 0000000..6c55492
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart
new file mode 100644
index 0000000..59f9881
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_17.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_17.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart
new file mode 100644
index 0000000..89d6903
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart
new file mode 100644
index 0000000..9aaee58
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart
new file mode 100644
index 0000000..1f2613c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart
new file mode 100644
index 0000000..5248eae
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart
new file mode 100644
index 0000000..ae259b3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart
new file mode 100644
index 0000000..315b8ba
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart
new file mode 100644
index 0000000..b3b060d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart
new file mode 100644
index 0000000..803d019
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_9 b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9
new file mode 100644
index 0000000..86963e3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.cps_ir_test;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_9", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart
new file mode 100644
index 0000000..f6cbe34
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_10_test.dart b/tests/compiler/dart2js/cps_ir/basic_10_test.dart
new file mode 100644
index 0000000..3d6ab6f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_11_test.dart b/tests/compiler/dart2js/cps_ir/basic_11_test.dart
new file mode 100644
index 0000000..eed3081
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_12_test.dart b/tests/compiler/dart2js/cps_ir/basic_12_test.dart
new file mode 100644
index 0000000..cbdbd19
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_13_test.dart b/tests/compiler/dart2js/cps_ir/basic_13_test.dart
new file mode 100644
index 0000000..e867b76
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_14_test.dart b/tests/compiler/dart2js/cps_ir/basic_14_test.dart
new file mode 100644
index 0000000..814bf20
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_15_test.dart b/tests/compiler/dart2js/cps_ir/basic_15_test.dart
new file mode 100644
index 0000000..72c06fe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_16_test.dart b/tests/compiler/dart2js/cps_ir/basic_16_test.dart
new file mode 100644
index 0000000..559ad5c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_1_test.dart b/tests/compiler/dart2js/cps_ir/basic_1_test.dart
new file mode 100644
index 0000000..711cb33
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_2_test.dart b/tests/compiler/dart2js/cps_ir/basic_2_test.dart
new file mode 100644
index 0000000..f5eb5b3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_3_test.dart b/tests/compiler/dart2js/cps_ir/basic_3_test.dart
new file mode 100644
index 0000000..5476c1f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_4_test.dart b/tests/compiler/dart2js/cps_ir/basic_4_test.dart
new file mode 100644
index 0000000..9cd8d85
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_5_test.dart b/tests/compiler/dart2js/cps_ir/basic_5_test.dart
new file mode 100644
index 0000000..e38ea0b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_6_test.dart b/tests/compiler/dart2js/cps_ir/basic_6_test.dart
new file mode 100644
index 0000000..0a79e84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_7_test.dart b/tests/compiler/dart2js/cps_ir/basic_7_test.dart
new file mode 100644
index 0000000..b411ab8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_8_test.dart b/tests/compiler/dart2js/cps_ir/basic_8_test.dart
new file mode 100644
index 0000000..03bc57c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_9_test.dart b/tests/compiler/dart2js/cps_ir/basic_9_test.dart
new file mode 100644
index 0000000..dd02afb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_10_test.dart b/tests/compiler/dart2js/cps_ir/closures_10_test.dart
new file mode 100644
index 0000000..e5d99a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_11_test.dart b/tests/compiler/dart2js/cps_ir/closures_11_test.dart
new file mode 100644
index 0000000..6012079
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_12_test.dart b/tests/compiler/dart2js/cps_ir/closures_12_test.dart
new file mode 100644
index 0000000..4bf040d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_13_test.dart b/tests/compiler/dart2js/cps_ir/closures_13_test.dart
new file mode 100644
index 0000000..f4c83b9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_14_test.dart b/tests/compiler/dart2js/cps_ir/closures_14_test.dart
new file mode 100644
index 0000000..c5198e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_15_test.dart b/tests/compiler/dart2js/cps_ir/closures_15_test.dart
new file mode 100644
index 0000000..f78f7a9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_1_test.dart b/tests/compiler/dart2js/cps_ir/closures_1_test.dart
new file mode 100644
index 0000000..9eb7749
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_2_test.dart b/tests/compiler/dart2js/cps_ir/closures_2_test.dart
new file mode 100644
index 0000000..ff5b698
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_3_test.dart b/tests/compiler/dart2js/cps_ir/closures_3_test.dart
new file mode 100644
index 0000000..cb19e78
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_4_test.dart b/tests/compiler/dart2js/cps_ir/closures_4_test.dart
new file mode 100644
index 0000000..66142a4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_5_test.dart b/tests/compiler/dart2js/cps_ir/closures_5_test.dart
new file mode 100644
index 0000000..5910347
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_6_test.dart b/tests/compiler/dart2js/cps_ir/closures_6_test.dart
new file mode 100644
index 0000000..9616d62
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_7_test.dart b/tests/compiler/dart2js/cps_ir/closures_7_test.dart
new file mode 100644
index 0000000..a95b1b2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_8_test.dart b/tests/compiler/dart2js/cps_ir/closures_8_test.dart
new file mode 100644
index 0000000..03b05f1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_9_test.dart b/tests/compiler/dart2js/cps_ir/closures_9_test.dart
new file mode 100644
index 0000000..3cf10ca
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart b/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart
new file mode 100644
index 0000000..e765c1d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.codeUnitAt_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("codeUnitAt_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart b/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart
new file mode 100644
index 0000000..9838b61
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.codeUnitAt_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("codeUnitAt_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_10_test.dart b/tests/compiler/dart2js/cps_ir/constructor_10_test.dart
new file mode 100644
index 0000000..ee3d425
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_11_test.dart b/tests/compiler/dart2js/cps_ir/constructor_11_test.dart
new file mode 100644
index 0000000..0b3002d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_12_test.dart b/tests/compiler/dart2js/cps_ir/constructor_12_test.dart
new file mode 100644
index 0000000..16442e3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_13_test.dart b/tests/compiler/dart2js/cps_ir/constructor_13_test.dart
new file mode 100644
index 0000000..084f2ef
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_14_test.dart b/tests/compiler/dart2js/cps_ir/constructor_14_test.dart
new file mode 100644
index 0000000..41903ef
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_1_test.dart b/tests/compiler/dart2js/cps_ir/constructor_1_test.dart
new file mode 100644
index 0000000..1acf661
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_2_test.dart b/tests/compiler/dart2js/cps_ir/constructor_2_test.dart
new file mode 100644
index 0000000..11fd0f8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_3_test.dart b/tests/compiler/dart2js/cps_ir/constructor_3_test.dart
new file mode 100644
index 0000000..46c02be
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_4_test.dart b/tests/compiler/dart2js/cps_ir/constructor_4_test.dart
new file mode 100644
index 0000000..11a392b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_5_test.dart b/tests/compiler/dart2js/cps_ir/constructor_5_test.dart
new file mode 100644
index 0000000..f95c26b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_6_test.dart b/tests/compiler/dart2js/cps_ir/constructor_6_test.dart
new file mode 100644
index 0000000..c37314b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_7_test.dart b/tests/compiler/dart2js/cps_ir/constructor_7_test.dart
new file mode 100644
index 0000000..0aeca1c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_8_test.dart b/tests/compiler/dart2js/cps_ir/constructor_8_test.dart
new file mode 100644
index 0000000..b22a96d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_9_test.dart b/tests/compiler/dart2js/cps_ir/constructor_9_test.dart
new file mode 100644
index 0000000..9fe1d90
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart
new file mode 100644
index 0000000..3efea51
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart
new file mode 100644
index 0000000..04ab770
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart
new file mode 100644
index 0000000..c3cd858
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart
new file mode 100644
index 0000000..b355d84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart
new file mode 100644
index 0000000..37ab62c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart
new file mode 100644
index 0000000..341be8e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart
new file mode 100644
index 0000000..3b9f94c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart
new file mode 100644
index 0000000..9a64a8c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart
new file mode 100644
index 0000000..7328a45
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js
new file mode 100644
index 0000000..758c03c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x - y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$sub$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js
new file mode 100644
index 0000000..8679a25
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x > y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$gt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js
new file mode 100644
index 0000000..b5ff041a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x < y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$lt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js
new file mode 100644
index 0000000..525a5d00
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$ge$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js
new file mode 100644
index 0000000..f434bb7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x <= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$le$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js
new file mode 100644
index 0000000..642f48b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x.remainder(y));
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.remainder$1$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js
new file mode 100644
index 0000000..aa6f727
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   var z = int.parse('1235');
+//   print(x is num);
+//   print(y is num);
+//   print(z is num);
+//   print(x.clamp(y, z));
+//   print(x is num);
+//   print(y is num);
+//   print(z is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1235", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(typeof z === "number");
+  P.print(J.clamp$2$n(x, y, z));
+  P.print(true);
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js
new file mode 100644
index 0000000..0ba4b75
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x + y);
+//   print(x is num);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$add$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js
new file mode 100644
index 0000000..1fb2867
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x * y);
+//   print(x is num);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$mul$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js
new file mode 100644
index 0000000..0e73f85
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x.compareTo(y));
+//   print(x is num);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.compareTo$1$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js
new file mode 100644
index 0000000..c614b75
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x / 2);
+//   print(x is num);
+//   print(y is num);
+//   print(x + y);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof y === "number";
+  P.print(J.$div$n(x, 2));
+  P.print(true);
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  P.print(x + y);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js
new file mode 100644
index 0000000..33c7bf9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x / y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$div$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js
new file mode 100644
index 0000000..915d2371
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x / 2);
+//   print(x is num);
+//   print(y is num);
+//   print(x * y);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof y === "number";
+  P.print(J.$div$n(x, 2));
+  P.print(true);
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  P.print(x * y);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
new file mode 100644
index 0000000..589d358
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
@@ -0,0 +1,30 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x / 2);
+//   print(x is num);
+//   print(y is num);
+//   print(x.compareTo(y));
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof y === "number";
+  P.print(J.$div$n(x, 2));
+  P.print(true);
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  if (x < y)
+    v0 = -1;
+  else if (x > y)
+    v0 = 1;
+  else if (x === y) {
+    v0 = x === 0;
+    v0 = v0 ? (y === 0 ? 1 / y < 0 : y < 0) === (v0 ? 1 / x < 0 : x < 0) ? 0 : (v0 ? 1 / x < 0 : x < 0) ? -1 : 1 : 0;
+  } else
+    v0 = isNaN(x) ? isNaN(y) ? 0 : 1 : -1;
+  P.print(v0);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js
new file mode 100644
index 0000000..3948378
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.toSigned(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.toSigned$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js
new file mode 100644
index 0000000..e2e290d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.toUnsigned(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.toUnsigned$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js
new file mode 100644
index 0000000..f251917
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.modInverse(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.modInverse$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js
new file mode 100644
index 0000000..9ebb55a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.gcd(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.gcd$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js
new file mode 100644
index 0000000..9294a75
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   var z = int.parse('1235');
+//   print(x is int);
+//   print(y is int);
+//   print(z is int);
+//   print(x.modPow(y, z));
+//   print(x is int);
+//   print(y is int);
+//   print(z is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1235", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(typeof z === "number" && Math.floor(z) === z);
+  P.print(J.modPow$2$i(x, y, z));
+  P.print(true);
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js
new file mode 100644
index 0000000..484f6a1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('3');
+//   var y = int.parse('a', onError: (e) => 'abcde');
+//   print(x is int);
+//   print(y is String);
+//   print(y.codeUnitAt(x));
+//   print(x is int);
+//   print(y is String);
+// }
+
+function() {
+  var x = P.int_parse("3", null, null), y = P.int_parse("a", new V.main_closure(), null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "string");
+  P.print(J.codeUnitAt$1$s(y, x));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js
new file mode 100644
index 0000000..b5ab697
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js
@@ -0,0 +1,47 @@
+// Expectation for test: 
+// import 'dart:math';
+// main() {
+//   var x = int.parse('3');
+//   var y = int.parse('1234');
+//   var z = int.parse('1236');
+//   var w = int.parse('2');
+//   print(x is num);
+//   print(sin(x));
+//   print(x is num);
+// 
+//   print(y is num);
+//   print(log(y));
+//   print(y is num);
+// 
+//   print(z is num);
+//   print(w is num);
+//   print(pow(z, w));
+//   print(z is num);
+//   print(w is num);
+// }
+
+function() {
+  var x = P.int_parse("3", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1236", null, null), w = P.int_parse("2", null, null), v0 = typeof x === "number", v1;
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(x));
+  P.print(Math.sin(x));
+  P.print(true);
+  v0 = typeof y === "number";
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  P.print(Math.log(y));
+  P.print(true);
+  v1 = typeof z === "number";
+  P.print(v1);
+  v0 = typeof w === "number";
+  P.print(v0);
+  if (!v1)
+    throw H.wrapException(H.argumentErrorValue(z));
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(w));
+  P.print(Math.pow(z, w));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js
new file mode 100644
index 0000000..5d7d8a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x % y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$mod$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js
new file mode 100644
index 0000000..43dfc17
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ~/ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$tdiv$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js
new file mode 100644
index 0000000..049ef54
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >> y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shr$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js
new file mode 100644
index 0000000..953fc10
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x << y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shl$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js
new file mode 100644
index 0000000..6e152f7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x & y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$and$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js
new file mode 100644
index 0000000..438d6dc7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x | y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$or$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js
new file mode 100644
index 0000000..43418b5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ^ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$xor$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js
new file mode 100644
index 0000000..758c03c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x - y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$sub$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js
new file mode 100644
index 0000000..b5ff041a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x < y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$lt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js
new file mode 100644
index 0000000..8679a25
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x > y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$gt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js
new file mode 100644
index 0000000..f434bb7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x <= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$le$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js
new file mode 100644
index 0000000..525a5d00
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$ge$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js
new file mode 100644
index 0000000..642f48b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x.remainder(y));
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.remainder$1$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js
new file mode 100644
index 0000000..3ce06f4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   var z = int.parse('1236');
+//   print(x is num);
+//   print(y is num);
+//   print(z is num);
+//   print(x.clamp(y, z));
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+//   print(z is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1236", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(typeof z === "number");
+  P.print(J.clamp$2$n(x, y, z));
+  P.print(true);
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js
new file mode 100644
index 0000000..10c7792
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x + y);
+//   print(x is num);
+//   print(y is num); // will stay as is-num because String could be a target of +
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$add$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js
new file mode 100644
index 0000000..4fa1574
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x * y);
+//   print(x is num);
+//   print(y is num); // will stay as is-num because String could be a target of *
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$mul$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js
new file mode 100644
index 0000000..33c7bf9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x / y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$div$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js
new file mode 100644
index 0000000..5d7d8a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x % y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$mod$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js
new file mode 100644
index 0000000..43dfc17
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ~/ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$tdiv$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js
new file mode 100644
index 0000000..049ef54
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >> y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shr$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js
new file mode 100644
index 0000000..953fc10
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x << y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shl$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js
new file mode 100644
index 0000000..6e152f7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x & y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$and$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js
new file mode 100644
index 0000000..438d6dc7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x | y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$or$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js
new file mode 100644
index 0000000..43418b5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ^ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$xor$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_1.js b/tests/compiler/dart2js/cps_ir/expected/basic_1.js
new file mode 100644
index 0000000..1cf4ed5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_1.js
@@ -0,0 +1,27 @@
+// Expectation for test: 
+// main() {
+//   var e = 1;
+//   var l = [1, 2, 3];
+//   var m = {'s': 1};
+// 
+//   print('(' ')');
+//   print('(${true})');
+//   print('(${1})');
+//   print('(${[1, 2, 3]})');
+//   print('(${{'s': 1}})');
+//   print('($e)');
+//   print('($l)');
+//   print('($m)');
+// }
+
+function() {
+  var l = [1, 2, 3], m = P.LinkedHashMap_LinkedHashMap$_literal(["s", 1]);
+  P.print("()");
+  P.print("(true)");
+  P.print("(1)");
+  P.print("(" + P.IterableBase_iterableToFullString([1, 2, 3], "[", "]") + ")");
+  P.print("(" + P.Maps_mapToString(P.LinkedHashMap_LinkedHashMap$_literal(["s", 1])) + ")");
+  P.print("(1)");
+  P.print("(" + P.IterableBase_iterableToFullString(l, "[", "]") + ")");
+  P.print("(" + P.Maps_mapToString(m) + ")");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_10.js b/tests/compiler/dart2js/cps_ir/expected/basic_10.js
new file mode 100644
index 0000000..cfd6571
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_10.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// main() {
+//   print(new DateTime.now().isBefore(new DateTime.now()));
+// }
+
+function() {
+  var v0 = Date.now() < Date.now(), line = v0 ? "true" : false === v0 ? "false" : String(v0);
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_11.js b/tests/compiler/dart2js/cps_ir/expected/basic_11.js
new file mode 100644
index 0000000..5f26f1c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_11.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// foo() { print(42); }
+// main() { foo(); }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_12.js b/tests/compiler/dart2js/cps_ir/expected/basic_12.js
new file mode 100644
index 0000000..084681f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_12.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// var foo = 42;
+// main() { print(foo); }
+
+function() {
+  var v0 = $.foo, line = v0 === 0 ? 1 / v0 < 0 ? "-0.0" : "" + v0 : "" + v0;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_13.js b/tests/compiler/dart2js/cps_ir/expected/basic_13.js
new file mode 100644
index 0000000..218ba31
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_13.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// get foo { print(42); }
+// main() { foo; }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_14.js b/tests/compiler/dart2js/cps_ir/expected/basic_14.js
new file mode 100644
index 0000000..a42876b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_14.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// var foo = 0;
+// main() { print(foo = 42); }
+
+function() {
+  var line = "" + 42;
+  $.foo = 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_15.js b/tests/compiler/dart2js/cps_ir/expected/basic_15.js
new file mode 100644
index 0000000..ea86609
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_15.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// set foo(x) { print(x); }
+// main() { foo = 42; }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_16.js b/tests/compiler/dart2js/cps_ir/expected/basic_16.js
new file mode 100644
index 0000000..0442443
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_16.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// foo() { print('X'); }
+// main() {
+//   assert(true);
+//   assert(false);
+//   assert(foo());
+//   print('Done');
+// }
+
+function() {
+  P.print("Done");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_2.js b/tests/compiler/dart2js/cps_ir/expected/basic_2.js
new file mode 100644
index 0000000..3f579fc
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_2.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// foo(a, [b = "b"]) { print(b); return b; }
+// bar(a, {b: "b", c: "c"}) { print(c); return c; }
+// main() {
+//   foo(0);
+//   foo(1, 2);
+//   bar(3);
+//   bar(4, b: 5);
+//   bar(6, c: 7);
+//   bar(8, b: 9, c: 10);
+// }
+
+function() {
+  P.print("b");
+  P.print(2);
+  P.print("c");
+  P.print("c");
+  P.print(7);
+  P.print(10);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_3.js b/tests/compiler/dart2js/cps_ir/expected/basic_3.js
new file mode 100644
index 0000000..3d8269f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_3.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// foo(a) {
+//   print(a);
+//   return a;
+// }
+// main() {
+//   var a = 10;
+//   var b = 1;
+//   var t;
+//   t = a;
+//   a = b;
+//   b = t;
+//   print(a);
+//   print(b);
+//   print(b);
+//   print(foo(a));
+// }
+
+function() {
+  P.print(1);
+  P.print(10);
+  P.print(10);
+  P.print(1);
+  P.print(1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_4.js b/tests/compiler/dart2js/cps_ir/expected/basic_4.js
new file mode 100644
index 0000000..68f024f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_4.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// foo() { print(42); return 42; }
+// main() { return foo(); }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+  return 42;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_5.js b/tests/compiler/dart2js/cps_ir/expected/basic_5.js
new file mode 100644
index 0000000..9027244
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_5.js
@@ -0,0 +1,5 @@
+// Expectation for test: 
+// main() {}
+
+function() {
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_6.js b/tests/compiler/dart2js/cps_ir/expected/basic_6.js
new file mode 100644
index 0000000..a6a2296
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_6.js
@@ -0,0 +1,6 @@
+// Expectation for test: 
+// main() { return 42; }
+
+function() {
+  return 42;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_7.js b/tests/compiler/dart2js/cps_ir/expected/basic_7.js
new file mode 100644
index 0000000..cd112ad
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_7.js
@@ -0,0 +1,5 @@
+// Expectation for test: 
+// main() { return; }
+
+function() {
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_8.js b/tests/compiler/dart2js/cps_ir/expected/basic_8.js
new file mode 100644
index 0000000..1d8cccd
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_8.js
@@ -0,0 +1,10 @@
+// Expectation for test: 
+// main() {
+//   print(new Set());
+//   print(new Set.from([1, 2, 3]));
+// }
+
+function() {
+  P.print(P._LinkedHashSet$(null));
+  P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_9.js b/tests/compiler/dart2js/cps_ir/expected/basic_9.js
new file mode 100644
index 0000000..b47ad6a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_9.js
@@ -0,0 +1,18 @@
+// Expectation for test: 
+// class C {}
+// main() {
+//   print(new C());
+// }
+
+function() {
+  var res = "Instance of '" + H.Primitives_objectTypeName(V.C$()) + "'";
+  if (typeof dartPrint == "function")
+    dartPrint(res);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(res);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(res);
+    print(res);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_1.js b/tests/compiler/dart2js/cps_ir/expected/closures_1.js
new file mode 100644
index 0000000..e8cc7ab
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_1.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   x = x + '1';
+//   print(a());
+// }
+
+function(x) {
+  P.print(J.$add$ns(x, "1"));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_10.js b/tests/compiler/dart2js/cps_ir/expected/closures_10.js
new file mode 100644
index 0000000..a628815
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_10.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// class A {
+//   a() => 1;
+//   b() => () => a();
+// }
+// main() {
+//   print(new A().b()());
+// }
+
+function() {
+  var line = H.S(new V.A_b_closure(V.A$()).call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_11.js b/tests/compiler/dart2js/cps_ir/expected/closures_11.js
new file mode 100644
index 0000000..e547d06
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_11.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// staticMethod(x) { print(x); return x; }
+// main(x) {
+//   var tearOff = staticMethod;
+//   print(tearOff(123));
+// }
+
+function(x) {
+  P.print(123);
+  P.print(123);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_12.js b/tests/compiler/dart2js/cps_ir/expected/closures_12.js
new file mode 100644
index 0000000..5078169
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_12.js
@@ -0,0 +1,13 @@
+// Expectation for test: 
+// class Foo {
+//   instanceMethod(x) => x;
+// }
+// main(x) {
+//   var tearOff = new Foo().instanceMethod;
+//   print(tearOff(123));
+// }
+
+function(x) {
+  V.Foo$();
+  P.print(123);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_13.js b/tests/compiler/dart2js/cps_ir/expected/closures_13.js
new file mode 100644
index 0000000..5a61827
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_13.js
@@ -0,0 +1,15 @@
+// Expectation for test: 
+// class Foo {
+//   instanceMethod(x) => x;
+// }
+// main(x) {
+//   var tearOff = new Foo().instanceMethod;
+//   print(tearOff(123));
+//   print(tearOff(321));
+// }
+
+function(x) {
+  V.Foo$();
+  P.print(123);
+  P.print(321);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_14.js b/tests/compiler/dart2js/cps_ir/expected/closures_14.js
new file mode 100644
index 0000000..5c27c7b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_14.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// class Foo {
+//   get getter {
+//     print('getter');
+//     return (x) => x;
+//   }
+// }
+// main(x) {
+//   var notTearOff = new Foo().getter;
+//   print(notTearOff(123));
+//   print(notTearOff(321));
+// }
+
+function(x) {
+  var notTearOff = new V.Foo_getter_closure();
+  V.Foo$();
+  P.print("getter");
+  P.print(notTearOff.call$1(123));
+  P.print(notTearOff.call$1(321));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_15.js b/tests/compiler/dart2js/cps_ir/expected/closures_15.js
new file mode 100644
index 0000000..46c7d38
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_15.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// class Foo {
+//   get getter {
+//     print('getter');
+//     return (x) => x;
+//   }
+// }
+// main(x) {
+//   var notTearOff = new Foo().getter;
+//   print(notTearOff(123));
+// }
+
+function(x) {
+  V.Foo$();
+  P.print("getter");
+  P.print(new V.Foo_getter_closure().call$1(123));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_2.js b/tests/compiler/dart2js/cps_ir/expected/closures_2.js
new file mode 100644
index 0000000..b5ffeebd
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_2.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   x = x + '1';
+//   print(a());
+//   return a;
+// }
+
+function(x) {
+  var _box_0 = {}, a = new V.main_a(_box_0);
+  _box_0.x = x;
+  _box_0.x = J.$add$ns(_box_0.x, "1");
+  P.print(a.call$0());
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_3.js b/tests/compiler/dart2js/cps_ir/expected/closures_3.js
new file mode 100644
index 0000000..69425f1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_3.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   print(a());
+// }
+
+function(x) {
+  P.print(x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_4.js b/tests/compiler/dart2js/cps_ir/expected/closures_4.js
new file mode 100644
index 0000000..02027fe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_4.js
@@ -0,0 +1,14 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   print(a());
+//   return a;
+// }
+
+function(x) {
+  var a = new V.main_a(x);
+  P.print(a.call$0());
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_5.js b/tests/compiler/dart2js/cps_ir/expected/closures_5.js
new file mode 100644
index 0000000..959b14a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_5.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () => x;
+//   x = x + 1;
+//   print(a());
+// }
+
+function() {
+  var _captured_x_0 = 122 + 1, line = _captured_x_0 === 0 ? 1 / _captured_x_0 < 0 ? "-0.0" : "" + _captured_x_0 : "" + _captured_x_0;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_6.js b/tests/compiler/dart2js/cps_ir/expected/closures_6.js
new file mode 100644
index 0000000..3ff087a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_6.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () => x;
+//   x = x + 1;
+//   print(a());
+//   return a;
+// }
+
+function() {
+  var _box_0 = {}, a = new V.main_closure(_box_0), line;
+  _box_0.x = 122;
+  ++_box_0.x;
+  line = H.S(a.call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_7.js b/tests/compiler/dart2js/cps_ir/expected/closures_7.js
new file mode 100644
index 0000000..4a16c92
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_7.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () {
+//     var y = x;
+//     return () => y;
+//   };
+//   x = x + 1;
+//   print(a()());
+// }
+
+function() {
+  var _captured_x_0 = 122 + 1, line = _captured_x_0 === 0 ? 1 / _captured_x_0 < 0 ? "-0.0" : "" + _captured_x_0 : "" + _captured_x_0;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_8.js b/tests/compiler/dart2js/cps_ir/expected/closures_8.js
new file mode 100644
index 0000000..35d033f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_8.js
@@ -0,0 +1,28 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () {
+//     var y = x;
+//     return () => y;
+//   };
+//   x = x + 1;
+//   print(a()());
+//   return a;
+// }
+
+function() {
+  var _box_0 = {}, a = new V.main_closure(_box_0), line;
+  _box_0.x = 122;
+  ++_box_0.x;
+  line = H.S(a.call$0().call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_9.js b/tests/compiler/dart2js/cps_ir/expected/closures_9.js
new file mode 100644
index 0000000..c11aa2d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_9.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var a;
+//   for (var i=0; i<10; i++) {
+//     a = () => i;
+//   }
+//   print(a());
+// }
+
+function() {
+  var a = null, i = 0, line;
+  for (; i < 10; a = new V.main_closure(i), ++i)
+    ;
+  line = H.S(a.call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js
new file mode 100644
index 0000000..92a1969
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js
@@ -0,0 +1,18 @@
+// Expectation for test: 
+// // Constant folding
+// main() {
+//   print('A'.codeUnitAt(0));
+// }
+
+function() {
+  var line = "" + 65;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
new file mode 100644
index 0000000..73e278b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// // Bounds checking
+// foo(s) {
+//   var sum = 0;
+//   for (int i = 0; i < s.length; i++) sum += s.codeUnitAt(i);
+//   return sum;
+// }
+// main() {
+//   print(foo('ABC'));
+//   print(foo('Hello'));
+// }
+
+function() {
+  var v0 = "ABC".length, sum = 0, i = 0;
+  for (; i < v0; sum += "ABC".charCodeAt(i), ++i)
+    ;
+  P.print(sum);
+  v0 = "Hello".length;
+  sum = 0;
+  for (i = 0; i < v0; sum += "Hello".charCodeAt(i), ++i)
+    ;
+  P.print(sum);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_1.js b/tests/compiler/dart2js/cps_ir/expected/constructor_1.js
new file mode 100644
index 0000000..21493c2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_1.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// class Base {
+//   var x;
+//   Base(this.x);
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x);
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  var line = 1 === 0 ? 1 / 1 < 0 ? "-0.0" : "" + 1 : "" + 1;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_10.js b/tests/compiler/dart2js/cps_ir/expected/constructor_10.js
new file mode 100644
index 0000000..c2148d0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_10.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// // Method to test: generative_constructor(C#)
+// class C<T> {
+//   var x;
+//   C() : x = new D<T>();
+// }
+// class D<T> {
+//   foo() => T;
+// }
+// main() {
+//   print(new C<int>().x.foo());
+// }
+
+function($T) {
+  return H.setRuntimeTypeInfo(new V.C(V.D$($T)), [$T]);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_11.js b/tests/compiler/dart2js/cps_ir/expected/constructor_11.js
new file mode 100644
index 0000000..9c0d6d0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_11.js
@@ -0,0 +1,22 @@
+// Expectation for test: 
+// class A {
+//   var x;
+//   A() : this.b(1);
+//   A.b(this.x);
+// }
+// main() {
+//   print(new A().x);
+// }
+
+function() {
+  var line = 1 === 0 ? 1 / 1 < 0 ? "-0.0" : "" + 1 : "" + 1;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_12.js b/tests/compiler/dart2js/cps_ir/expected/constructor_12.js
new file mode 100644
index 0000000..d892327
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_12.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// class Foo {
+//   factory Foo.make(x) {
+//     print('Foo');
+//     return new Foo.create(x);
+//   }
+//   var x;
+//   Foo.create(this.x);
+// }
+// main() {
+//   print(new Foo.make(5));
+// }
+
+function() {
+  P.print("Foo");
+  P.print(new V.Foo(5));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_13.js b/tests/compiler/dart2js/cps_ir/expected/constructor_13.js
new file mode 100644
index 0000000..074cf69
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_13.js
@@ -0,0 +1,22 @@
+// Expectation for test: 
+// class Foo {
+//   factory Foo.make(x) = Foo.create;
+//   var x;
+//   Foo.create(this.x);
+// }
+// main() {
+//   print(new Foo.make(5));
+// }
+
+function() {
+  var res = "Instance of '" + H.Primitives_objectTypeName(new V.Foo(5)) + "'";
+  if (typeof dartPrint == "function")
+    dartPrint(res);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(res);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(res);
+    print(res);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_14.js b/tests/compiler/dart2js/cps_ir/expected/constructor_14.js
new file mode 100644
index 0000000..fe479f9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_14.js
@@ -0,0 +1,18 @@
+// Expectation for test: 
+// class A {
+//   factory A(x) = B<int>;
+//   get typevar;
+// }
+// class B<T> implements A {
+//   var x;
+//   B(this.x);
+// 
+//   get typevar => T;
+// }
+// main() {
+//   new A(5).typevar;
+// }
+
+function() {
+  V.B$(5, P.$int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_2.js b/tests/compiler/dart2js/cps_ir/expected/constructor_2.js
new file mode 100644
index 0000000..94d3b4e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_2.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// class Base {
+//   var x;
+//   Base(this.x);
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x) {
+//     print(x);
+//   }
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  P.print(1);
+  P.print(1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_3.js b/tests/compiler/dart2js/cps_ir/expected/constructor_3.js
new file mode 100644
index 0000000..0f14d28
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_3.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// class Base0 {
+//   Base0() {
+//     print('Base0');
+//   }
+// }
+// class Base extends Base0 {
+//   var x;
+//   Base(this.x);
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x) {
+//     print(x);
+//   }
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  P.print("Base0");
+  P.print(1);
+  P.print(1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_4.js b/tests/compiler/dart2js/cps_ir/expected/constructor_4.js
new file mode 100644
index 0000000..7253134
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_4.js
@@ -0,0 +1,30 @@
+// Expectation for test: 
+// class Base0 {
+//   Base0() {
+//     print('Base0');
+//   }
+// }
+// class Base extends Base0 {
+//   var x;
+//   Base(x1) : x = (() => ++x1) {
+//     print(x1); // use boxed x1
+//   }
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x) {
+//     print(x);
+//   }
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  var _box_0 = {};
+  _box_0.x1 = 1;
+  P.print("Base0");
+  P.print(_box_0.x1);
+  P.print(1);
+  P.print(new V.Base_closure(_box_0));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_5.js b/tests/compiler/dart2js/cps_ir/expected/constructor_5.js
new file mode 100644
index 0000000..ed704e1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_5.js
@@ -0,0 +1,28 @@
+// Expectation for test: 
+// foo(x) {
+//   print(x);
+// }
+// class Base {
+//   var x1 = foo('x1');
+//   var x2;
+//   var x3 = foo('x3');
+//   Base() : x2 = foo('x2');
+// }
+// class Sub extends Base {
+//   var y1 = foo('y1');
+//   var y2;
+//   var y3;
+//   Sub() : y2 = foo('y2'), super(), y3 = foo('y3');
+// }
+// main() {
+//   new Sub();
+// }
+
+function() {
+  V.foo("y1");
+  V.foo("y2");
+  V.foo("x1");
+  V.foo("x3");
+  V.foo("x2");
+  V.foo("y3");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_6.js b/tests/compiler/dart2js/cps_ir/expected/constructor_6.js
new file mode 100644
index 0000000..66d5ae5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_6.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// class Bar {
+//   Bar(x, {y, z: 'z', w: '_', q}) {
+//     print(x);
+//     print(y);
+//     print(z);
+//     print(w);
+//     print(q);
+//   }
+// }
+// class Foo extends Bar {
+//   Foo() : super('x', y: 'y', w: 'w');
+// }
+// main() {
+//   new Foo();
+// }
+
+function() {
+  P.print("x");
+  P.print("y");
+  P.print("z");
+  P.print("w");
+  P.print(null);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_7.js b/tests/compiler/dart2js/cps_ir/expected/constructor_7.js
new file mode 100644
index 0000000..8474ee4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_7.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => T;
+// }
+// main() {
+//   print(new C<int>().foo());
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.C$(P.$int), 0))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_8.js b/tests/compiler/dart2js/cps_ir/expected/constructor_8.js
new file mode 100644
index 0000000..e4a2ea6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_8.js
@@ -0,0 +1,22 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => C;
+// }
+// main() {
+//   print(new C<int>().foo());
+// }
+
+function() {
+  var line;
+  V.C$();
+  line = H.S(C.Type_C_cdS);
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_9.js b/tests/compiler/dart2js/cps_ir/expected/constructor_9.js
new file mode 100644
index 0000000..05928b3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_9.js
@@ -0,0 +1,15 @@
+// Expectation for test: 
+// // Method to test: generative_constructor(C#)
+// class C<T> {
+//   C() { print(T); }
+//   foo() => print(T);
+// }
+// main() {
+//   new C<int>();
+// }
+
+function($T) {
+  var v0 = H.setRuntimeTypeInfo(new V.C(), [$T]);
+  v0.C$0();
+  return v0;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
new file mode 100644
index 0000000..950d594
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
@@ -0,0 +1,9 @@
+// Expectation for test: 
+// main() {
+//   while (true);
+// }
+
+function() {
+  while (true)
+    ;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
new file mode 100644
index 0000000..79c2ddd
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
@@ -0,0 +1,33 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//   while (true) {
+//     l: while (true) {
+//       while (foo(true)) {
+//         if (foo(false)) break l;
+//       }
+//       print(1);
+//     }
+//     print(2);
+//   }
+// }
+
+function() {
+  L1:
+    while (true)
+      L0:
+        while (true)
+          while (true) {
+            P.print(true);
+            if (false) {
+              P.print(1);
+              continue L0;
+            }
+            P.print(false);
+            if (false) {
+              P.print(2);
+              continue L1;
+            }
+          }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
new file mode 100644
index 0000000..514ed7b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
@@ -0,0 +1,26 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//   for (int i = 0; foo(true); i = foo(i)) {
+//     print(1);
+//     if (foo(false)) break;
+//   }
+//   print(2);
+// }
+
+function() {
+  while (true) {
+    P.print(true);
+    if (true === true) {
+      P.print(1);
+      P.print(false);
+      if (false !== true) {
+        P.print(0);
+        continue;
+      }
+    }
+    P.print(2);
+    return null;
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
new file mode 100644
index 0000000..00099d0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//  foo(false);
+//  if (foo(true)) {
+//    print(1);
+//  } else {
+//    print(2);
+//  }
+//  print(3);
+// }
+
+function() {
+  P.print(false);
+  P.print(true);
+  true ? P.print(1) : P.print(2);
+  P.print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
new file mode 100644
index 0000000..78c0641
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
@@ -0,0 +1,27 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//  foo(false);
+//  if (foo(true)) {
+//    print(1);
+//    print(1);
+//  } else {
+//    print(2);
+//    print(2);
+//  }
+//  print(3);
+// }
+
+function() {
+  P.print(false);
+  P.print(true);
+  if (true) {
+    P.print(1);
+    P.print(1);
+  } else {
+    P.print(2);
+    P.print(2);
+  }
+  P.print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js
new file mode 100644
index 0000000..4530b7e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// main() {
+//   if (1) {
+//     print('bad');
+//   } else {
+//     print('good');
+//   }
+// }
+
+function() {
+  P.print("good");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js
new file mode 100644
index 0000000..e4f20e1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js
@@ -0,0 +1,14 @@
+// Expectation for test: 
+// foo() { print('2'); return 2; }
+// main() {
+//   if (foo()) {
+//     print('bad');
+//   } else {
+//     print('good');
+//   }
+// }
+
+function() {
+  P.print("2");
+  P.print("good");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js
new file mode 100644
index 0000000..bcb67d3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// main() {
+//   var list = [1,2,3,4,5,6];
+//   for (var x in list) {
+//     print(x);
+//   }
+// }
+
+function() {
+  var list = [1, 2, 3, 4, 5, 6], i = 0, line;
+  for (; i < 6; ++i) {
+    line = H.S(list[i]);
+    if (typeof dartPrint == "function")
+      dartPrint(line);
+    else if (typeof console == "object" && typeof console.log != "undefined")
+      console.log(line);
+    else if (!(typeof window == "object")) {
+      if (!(typeof print == "function"))
+        throw "Unable to print message: " + String(line);
+      print(line);
+    }
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js
new file mode 100644
index 0000000..637d654
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var xs = ['x', 'y', 'z'], ys = ['A', 'B', 'C'];
+//   var xit = xs.iterator, yit = ys.iterator;
+//   while (xit.moveNext() && yit.moveNext()) {
+//     print(xit.current);
+//     print(yit.current);
+//   }
+// }
+
+function() {
+  var xs = ["x", "y", "z"], ys = ["A", "B", "C"], i = 0, i1 = 0, current, current1;
+  for (; i < 3; ++i, ++i1) {
+    current = xs[i];
+    if (!(i1 < 3))
+      break;
+    current1 = ys[i1];
+    P.print(current);
+    P.print(current1);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/gvn_1.js b/tests/compiler/dart2js/cps_ir/expected/gvn_1.js
new file mode 100644
index 0000000..1307a74
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/gvn_1.js
@@ -0,0 +1,58 @@
+// Expectation for test: 
+// foo(x, list) {
+//   var sum = 0;
+//   for (int k = 0; k < 10; k++) {
+//     // Everything can be hoisted out up to the index access which is
+//     // blocked by the bounds check.
+//     var a = x.left.left;
+//     var b = x.left.right;
+//     var c = x.right.left;
+//     var d = x.right.right;
+//     var i = a.value + c.value;
+//     var j = b.value + d.value;
+//     var z = list[i * j] + i;
+//     sum += z;
+//   }
+//   return sum;
+// }
+// // Use a different class for each level in the tree, so type inference
+// // is not confused.
+// class Root {
+//   Branch left, right;
+//   Root(this.left, this.right);
+// }
+// class Branch {
+//   Leaf left, right;
+//   Branch(this.left, this.right);
+// }
+// class Leaf {
+//   int value;
+//   Leaf(this.value);
+// }
+// main() {
+//   var x1 = new Leaf(1);
+//   var x2 = new Leaf(10);
+//   var x3 = new Leaf(20);
+//   var x4 = new Leaf(-10);
+//   var y1 = new Branch(x1, x2);
+//   var y2 = new Branch(x3, x4);
+//   var z  = new Root(y1, y2);
+//   print(foo(z, [1,2,3,4,5,6,7,8,9,10]));
+// }
+
+function() {
+  var v0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], i = 1 + 20, v1 = i * (10 + -10), sum = 0, k = 0, line;
+  for (; k < 10; sum += i + v0[v1], ++k)
+    if (v1 < 0 || v1 >= 10)
+      return H.ioore(v0, v1);
+  line = sum === 0 ? 1 / sum < 0 ? "-0.0" : "" + sum : "" + sum;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js b/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js
new file mode 100644
index 0000000..ed58ff0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   var g = 1;
+// 
+//   var x = g + 3;
+//   print(x);
+// }
+
+function() {
+  var line = "" + 4;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js b/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js
new file mode 100644
index 0000000..fdb0701
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   var l = ['hest', ['h', 'e', 's', 't']];
+//   print(l.length);
+//   for (int i  = 0; i < l.length; i++) {
+//     var x = l[i];
+//     for (int j = 0; j < x.length; j++) {
+//       print(x[j]);
+//     }
+//   }
+// }
+
+function() {
+  var l = ["hest", ["h", "e", "s", "t"]], i = 0, x, j;
+  for (P.print(2); i < 2; ++i) {
+    x = l[i];
+    for (j = 0; j < x.length; ++j)
+      P.print(x[j]);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/literals_1.js b/tests/compiler/dart2js/cps_ir/expected/literals_1.js
new file mode 100644
index 0000000..ef654f5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/literals_1.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   print([]);
+//   print([1]);
+//   print([1, 2]);
+//   print([1, [1, 2]]);
+//   print({});
+//   print({1: 2});
+//   print({[1, 2]: [3, 4]});
+// }
+
+function() {
+  P.print([]);
+  P.print([1]);
+  P.print([1, 2]);
+  P.print([1, [1, 2]]);
+  P.print(P.LinkedHashMap_LinkedHashMap$_empty());
+  P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
+  P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_1.js b/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
new file mode 100644
index 0000000..5e39b1e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a, b) => ((a & 0xff0000) >> 1) & b;
+// main() {
+//   print(foo(123, 234));
+//   print(foo(0, 2));
+// }
+
+function() {
+  P.print((123 & 16711680) >>> 1 & 234);
+  P.print((0 & 16711680) >>> 1 & 2);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_2.js b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
new file mode 100644
index 0000000..8d6d52d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => ~a;
+// main() {
+//   print(foo(1));
+//   print(foo(10));
+// }
+
+function() {
+  P.print(~1 >>> 0);
+  P.print(~10 >>> 0);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_3.js b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
new file mode 100644
index 0000000..ff5d25d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// // Method to test: function(foo)
+// foo(a) => a % 13;
+// main() {
+//   print(foo(5));
+//   print(foo(-100));
+// }
+
+function(a) {
+  var result = a % 13;
+  return result === 0 ? 0 : result > 0 ? result : 13 < 0 ? result - 13 : result + 13;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_4.js b/tests/compiler/dart2js/cps_ir/expected/operators2_4.js
new file mode 100644
index 0000000..4f5c0f0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_4.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => a % 13;
+// main() {
+//   print(foo(5));
+//   print(foo(100));
+// }
+
+function() {
+  P.print(5 % 13);
+  P.print(100 % 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_5.js b/tests/compiler/dart2js/cps_ir/expected/operators2_5.js
new file mode 100644
index 0000000..a07d368
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_5.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => a.remainder(13);
+// main() {
+//   print(foo(5));
+//   print(foo(-100));
+// }
+
+function() {
+  P.print(5 % 13);
+  P.print(-100 % 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_6.js b/tests/compiler/dart2js/cps_ir/expected/operators2_6.js
new file mode 100644
index 0000000..79fe43a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_6.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// // Method to test: function(foo)
+// foo(a) => a ~/ 13;
+// main() {
+//   print(foo(5));
+//   print(foo(-100));
+// }
+
+function(a) {
+  return (a | 0) === a && (13 | 0) === 13 ? a / 13 | 0 : C.JSNumber_methods.toInt$0(a / 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_7.js b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
new file mode 100644
index 0000000..837393f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => a ~/ 13;
+// main() {
+//   print(foo(5));
+//   print(foo(100));
+// }
+
+function() {
+  P.print(5 / 13 | 0);
+  P.print(100 / 13 | 0);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_8.js b/tests/compiler/dart2js/cps_ir/expected/operators2_8.js
new file mode 100644
index 0000000..2f1ce60
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_8.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// // Method to test: function(foo)
+// foo(a) => a ~/ 13;
+// main() {
+//   print(foo(5));
+//   print(foo(8000000000));
+// }
+
+function(a) {
+  return (a | 0) === a && (13 | 0) === 13 ? a / 13 | 0 : C.JSNumber_methods.toInt$0(a / 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_1.js b/tests/compiler/dart2js/cps_ir/expected/operators_1.js
new file mode 100644
index 0000000..dd0ddca
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_1.js
@@ -0,0 +1,6 @@
+// Expectation for test: 
+// main() { return true ? 42 : 'foo'; }
+
+function() {
+  return 42;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_2.js b/tests/compiler/dart2js/cps_ir/expected/operators_2.js
new file mode 100644
index 0000000..4b6236b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_2.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// var x = 1;
+// foo() => ++x > 10;
+// main() {
+//   print(foo() ? "hello world" : "bad bad");
+// }
+
+function() {
+  var v0 = $.x + 1;
+  $.x = v0;
+  v0 = v0 > 10 ? "hello world" : "bad bad";
+  if (typeof dartPrint == "function")
+    dartPrint(v0);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(v0);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(v0);
+    print(v0);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_3.js b/tests/compiler/dart2js/cps_ir/expected/operators_3.js
new file mode 100644
index 0000000..525b95f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_3.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// var x = 1;
+// get foo => ++x > 10;
+// main() {
+//   print(foo ? "hello world" : "bad bad");
+// }
+
+function() {
+  var v0 = $.x + 1;
+  $.x = v0;
+  v0 = v0 > 10 ? "hello world" : "bad bad";
+  if (typeof dartPrint == "function")
+    dartPrint(v0);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(v0);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(v0);
+    print(v0);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_4.js b/tests/compiler/dart2js/cps_ir/expected/operators_4.js
new file mode 100644
index 0000000..f86a490
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_4.js
@@ -0,0 +1,30 @@
+// Expectation for test: 
+// var x = 1;
+// get foo => ++x > 10;
+// main() { print(foo && foo); }
+
+function() {
+  var v0 = $.x + 1, line;
+  $.x = v0;
+  L0: {
+    if (v0 > 10) {
+      $.x = v0 = $.x + 1;
+      if (v0 > 10) {
+        line = "true";
+        break L0;
+      }
+      v0 = false;
+    } else
+      v0 = false;
+    line = false === v0 ? "false" : String(v0);
+  }
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_5.js b/tests/compiler/dart2js/cps_ir/expected/operators_5.js
new file mode 100644
index 0000000..3ff812c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_5.js
@@ -0,0 +1,28 @@
+// Expectation for test: 
+// var x = 1;
+// get foo => ++x > 10;
+// main() { print(foo || foo); }
+
+function() {
+  var v0 = $.x + 1, line;
+  $.x = v0;
+  L0: {
+    if (!(v0 > 10)) {
+      $.x = v0 = $.x + 1;
+      if (!(v0 > 10)) {
+        line = false === false ? "false" : String(false);
+        break L0;
+      }
+    }
+    line = "true";
+  }
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_6.js b/tests/compiler/dart2js/cps_ir/expected/operators_6.js
new file mode 100644
index 0000000..10e71da
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_6.js
@@ -0,0 +1,7 @@
+// Expectation for test: 
+// get foo => foo;
+// main() { print(foo || foo); }
+
+function() {
+  V.foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_7.js b/tests/compiler/dart2js/cps_ir/expected/operators_7.js
new file mode 100644
index 0000000..b81aaa9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_7.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// class Foo {
+//   operator[]=(index, value) {
+//     print(value);
+//   }
+// }
+// main() {
+//   var foo = new Foo();
+//   foo[5] = 6;
+// }
+
+function() {
+  var line = "" + 6;
+  V.Foo$();
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_8.js b/tests/compiler/dart2js/cps_ir/expected/operators_8.js
new file mode 100644
index 0000000..3f1c27e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_8.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var list = [1, 2, 3];
+//   list[1] = 6;
+//   print(list);
+// }
+
+function() {
+  var list = [1, 2, 3], res;
+  list[1] = 6;
+  res = P.IterableBase_iterableToFullString(list, "[", "]");
+  if (typeof dartPrint == "function")
+    dartPrint(res);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(res);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(res);
+    print(res);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js
new file mode 100644
index 0000000..914008d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => print(T);
+// }
+// 
+// main() {
+//   new C<int>().foo();
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.C$(P.$int), 0))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js
new file mode 100644
index 0000000..d22895f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// class C<T, U> {
+//   foo() => print(U);
+// }
+// 
+// class D extends C<int, double> {}
+// 
+// main() {
+//   new D().foo();
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getRuntimeTypeArgument(V.D$(), "C", 1))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js
new file mode 100644
index 0000000..435bb62
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => new D<C<T>>();
+// }
+// class D<T> {
+//   bar() => T;
+// }
+// main() {
+//   print(new C<int>().foo().bar());
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.D$([V.C, H.getTypeArgumentByIndex(V.C$(P.$int), 0)]), 0))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js
new file mode 100644
index 0000000..823dbe9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// // Method to test: generative_constructor(C#)
+// class C<X, Y, Z> {
+//   foo() => 'C<$X $Y, $Z>';
+// }
+// main() {
+//   new C<C, int, String>().foo();
+// }
+
+function($X, $Y, $Z) {
+  return H.setRuntimeTypeInfo(new V.C(), [$X, $Y, $Z]);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_1.js b/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
new file mode 100644
index 0000000..4c7ee26
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
@@ -0,0 +1,26 @@
+// Expectation for test: 
+// class Base {
+//   m(x) {
+//     print(x+1);
+//   }
+// }
+// class Sub extends Base {
+//   m(x) => super.m(x+10);
+// }
+// main() {
+//   new Sub().m(100);
+// }
+
+function() {
+  var line = "" + (100 + 10 + 1);
+  V.Sub$();
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_2.js b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
new file mode 100644
index 0000000..13b1d21
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
@@ -0,0 +1,29 @@
+// Expectation for test: 
+// // TODO(sigmund): change this to check method "function(Sub#+)" once we provide
+// // a way to disable inlining of Sub#+, which is compiled to something like:
+// // function(x) {
+// //   var v0, v1, v2;
+// //   v0 = 1;
+// //   v1 = J.getInterceptor$ns(x).$add(x, v0);
+// //   v2 = this;
+// //   return V.Base.prototype.$add.call(null, v2, v1);
+// // }
+// 
+// class Base {
+//   m(x) {
+//     print(x+1000);
+//   }
+//   operator+(x) => m(x+10);
+// }
+// class Sub extends Base {
+//   m(x) => super.m(x+100);
+//   operator+(x) => super + (x+1);
+// }
+// main() {
+//   new Sub() + 10000;
+// }
+
+function() {
+  var v0 = V.Sub$();
+  V.Base.prototype.$add.call(v0, v0, 10000 + 1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_3.js b/tests/compiler/dart2js/cps_ir/expected/supercall_3.js
new file mode 100644
index 0000000..ffc1752
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_3.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// class Base {
+//   var field = 123;
+// }
+// class Sub extends Base {
+//   m(x) => x + super.field;
+// }
+// main() {
+//   print(new Sub().m(10));
+// }
+
+function() {
+  var line = "" + (10 + V.Sub$().field);
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/gvn_1_test.dart b/tests/compiler/dart2js/cps_ir/gvn_1_test.dart
new file mode 100644
index 0000000..e341e5d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/gvn_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.gvn_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("gvn_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart
new file mode 100644
index 0000000..e807927
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x - y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart
new file mode 100644
index 0000000..85143eb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x > y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart
new file mode 100644
index 0000000..eca7811
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x < y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart
new file mode 100644
index 0000000..7ad1e67
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart
new file mode 100644
index 0000000..6083767
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x <= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart
new file mode 100644
index 0000000..09c8e76
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x.remainder(y));
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart
new file mode 100644
index 0000000..5724188
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart
@@ -0,0 +1,12 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  var z = int.parse('1235');
+  print(x is num);
+  print(y is num);
+  print(z is num);
+  print(x.clamp(y, z));
+  print(x is num);
+  print(y is num);
+  print(z is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart
new file mode 100644
index 0000000..f7655f4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x + y);
+  print(x is num);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart
new file mode 100644
index 0000000..20dd689
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x * y);
+  print(x is num);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart
new file mode 100644
index 0000000..aae68b8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x.compareTo(y));
+  print(x is num);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart
new file mode 100644
index 0000000..a61936e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x / 2);
+  print(x is num);
+  print(y is num);
+  print(x + y);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart
new file mode 100644
index 0000000..2021ca9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x / y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart
new file mode 100644
index 0000000..d8a5b4d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x / 2);
+  print(x is num);
+  print(y is num);
+  print(x * y);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart
new file mode 100644
index 0000000..ae28a0e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x / 2);
+  print(x is num);
+  print(y is num);
+  print(x.compareTo(y));
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart
new file mode 100644
index 0000000..988edd7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.toSigned(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart
new file mode 100644
index 0000000..c727aa8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.toUnsigned(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart
new file mode 100644
index 0000000..1b2aef6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.modInverse(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart
new file mode 100644
index 0000000..740bb92
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.gcd(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart
new file mode 100644
index 0000000..dfdd56b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart
@@ -0,0 +1,12 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  var z = int.parse('1235');
+  print(x is int);
+  print(y is int);
+  print(z is int);
+  print(x.modPow(y, z));
+  print(x is int);
+  print(y is int);
+  print(z is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart
new file mode 100644
index 0000000..b53d2df
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('3');
+  var y = int.parse('a', onError: (e) => 'abcde');
+  print(x is int);
+  print(y is String);
+  print(y.codeUnitAt(x));
+  print(x is int);
+  print(y is String);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart
new file mode 100644
index 0000000..cbea9617
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart
@@ -0,0 +1,20 @@
+import 'dart:math';
+main() {
+  var x = int.parse('3');
+  var y = int.parse('1234');
+  var z = int.parse('1236');
+  var w = int.parse('2');
+  print(x is num);
+  print(sin(x));
+  print(x is num);
+
+  print(y is num);
+  print(log(y));
+  print(y is num);
+
+  print(z is num);
+  print(w is num);
+  print(pow(z, w));
+  print(z is num);
+  print(w is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart
new file mode 100644
index 0000000..8353ddf
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x % y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart
new file mode 100644
index 0000000..958363a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ~/ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart
new file mode 100644
index 0000000..c46235b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >> y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart
new file mode 100644
index 0000000..461da84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x << y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart
new file mode 100644
index 0000000..c5f7d72
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x & y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart
new file mode 100644
index 0000000..9aef9e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x | y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart
new file mode 100644
index 0000000..22266c7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ^ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart
new file mode 100644
index 0000000..e807927
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x - y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart
new file mode 100644
index 0000000..eca7811
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x < y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart
new file mode 100644
index 0000000..85143eb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x > y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart
new file mode 100644
index 0000000..6083767
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x <= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart
new file mode 100644
index 0000000..7ad1e67
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart
new file mode 100644
index 0000000..09c8e76
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x.remainder(y));
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart
new file mode 100644
index 0000000..227e62e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart
@@ -0,0 +1,12 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  var z = int.parse('1236');
+  print(x is num);
+  print(y is num);
+  print(z is num);
+  print(x.clamp(y, z));
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+  print(z is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart
new file mode 100644
index 0000000..c757d08
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x + y);
+  print(x is num);
+  print(y is num); // will stay as is-num because String could be a target of +
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart
new file mode 100644
index 0000000..9dd57c3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x * y);
+  print(x is num);
+  print(y is num); // will stay as is-num because String could be a target of *
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart
new file mode 100644
index 0000000..2021ca9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x / y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart
new file mode 100644
index 0000000..8353ddf
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x % y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart
new file mode 100644
index 0000000..958363a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ~/ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart
new file mode 100644
index 0000000..c46235b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >> y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart
new file mode 100644
index 0000000..461da84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x << y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart
new file mode 100644
index 0000000..c5f7d72
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x & y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart
new file mode 100644
index 0000000..9aef9e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x | y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart
new file mode 100644
index 0000000..22266c7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ^ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_1.dart b/tests/compiler/dart2js/cps_ir/input/basic_1.dart
new file mode 100644
index 0000000..ee77081
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_1.dart
@@ -0,0 +1,14 @@
+main() {
+  var e = 1;
+  var l = [1, 2, 3];
+  var m = {'s': 1};
+
+  print('(' ')');
+  print('(${true})');
+  print('(${1})');
+  print('(${[1, 2, 3]})');
+  print('(${{'s': 1}})');
+  print('($e)');
+  print('($l)');
+  print('($m)');
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_10.dart b/tests/compiler/dart2js/cps_ir/input/basic_10.dart
new file mode 100644
index 0000000..e5a56a0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_10.dart
@@ -0,0 +1,3 @@
+main() {
+  print(new DateTime.now().isBefore(new DateTime.now()));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_11.dart b/tests/compiler/dart2js/cps_ir/input/basic_11.dart
new file mode 100644
index 0000000..34c8802
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_11.dart
@@ -0,0 +1,3 @@
+foo() { print(42); }
+main() { foo(); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_12.dart b/tests/compiler/dart2js/cps_ir/input/basic_12.dart
new file mode 100644
index 0000000..d48fb05
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_12.dart
@@ -0,0 +1,3 @@
+var foo = 42;
+main() { print(foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_13.dart b/tests/compiler/dart2js/cps_ir/input/basic_13.dart
new file mode 100644
index 0000000..3582183
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_13.dart
@@ -0,0 +1,3 @@
+get foo { print(42); }
+main() { foo; }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_14.dart b/tests/compiler/dart2js/cps_ir/input/basic_14.dart
new file mode 100644
index 0000000..f39e531
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_14.dart
@@ -0,0 +1,3 @@
+var foo = 0;
+main() { print(foo = 42); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_15.dart b/tests/compiler/dart2js/cps_ir/input/basic_15.dart
new file mode 100644
index 0000000..5ecc7ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_15.dart
@@ -0,0 +1,3 @@
+set foo(x) { print(x); }
+main() { foo = 42; }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_16.dart b/tests/compiler/dart2js/cps_ir/input/basic_16.dart
new file mode 100644
index 0000000..749ce68
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_16.dart
@@ -0,0 +1,7 @@
+foo() { print('X'); }
+main() {
+  assert(true);
+  assert(false);
+  assert(foo());
+  print('Done');
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_2.dart b/tests/compiler/dart2js/cps_ir/input/basic_2.dart
new file mode 100644
index 0000000..6305610
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_2.dart
@@ -0,0 +1,11 @@
+foo(a, [b = "b"]) { print(b); return b; }
+bar(a, {b: "b", c: "c"}) { print(c); return c; }
+main() {
+  foo(0);
+  foo(1, 2);
+  bar(3);
+  bar(4, b: 5);
+  bar(6, c: 7);
+  bar(8, b: 9, c: 10);
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_3.dart b/tests/compiler/dart2js/cps_ir/input/basic_3.dart
new file mode 100644
index 0000000..95ffd22
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_3.dart
@@ -0,0 +1,17 @@
+foo(a) {
+  print(a);
+  return a;
+}
+main() {
+  var a = 10;
+  var b = 1;
+  var t;
+  t = a;
+  a = b;
+  b = t;
+  print(a);
+  print(b);
+  print(b);
+  print(foo(a));
+}
+  
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_4.dart b/tests/compiler/dart2js/cps_ir/input/basic_4.dart
new file mode 100644
index 0000000..1e74c32
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_4.dart
@@ -0,0 +1,3 @@
+foo() { print(42); return 42; }
+main() { return foo(); }
+  
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_5.dart b/tests/compiler/dart2js/cps_ir/input/basic_5.dart
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_5.dart
@@ -0,0 +1 @@
+main() {}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_6.dart b/tests/compiler/dart2js/cps_ir/input/basic_6.dart
new file mode 100644
index 0000000..f55f628
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_6.dart
@@ -0,0 +1 @@
+main() { return 42; }
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_7.dart b/tests/compiler/dart2js/cps_ir/input/basic_7.dart
new file mode 100644
index 0000000..98b304d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_7.dart
@@ -0,0 +1 @@
+main() { return; }
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_8.dart b/tests/compiler/dart2js/cps_ir/input/basic_8.dart
new file mode 100644
index 0000000..e6ebb66
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_8.dart
@@ -0,0 +1,4 @@
+main() {
+  print(new Set());
+  print(new Set.from([1, 2, 3]));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_9.dart b/tests/compiler/dart2js/cps_ir/input/basic_9.dart
new file mode 100644
index 0000000..15a7643
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_9.dart
@@ -0,0 +1,4 @@
+class C {}
+main() {
+  print(new C());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_1.dart b/tests/compiler/dart2js/cps_ir/input/closures_1.dart
new file mode 100644
index 0000000..f47a0a0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_1.dart
@@ -0,0 +1,8 @@
+main(x) {
+  a() {
+    return x;
+  }
+  x = x + '1';
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_10.dart b/tests/compiler/dart2js/cps_ir/input/closures_10.dart
new file mode 100644
index 0000000..542d012
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_10.dart
@@ -0,0 +1,8 @@
+class A {
+  a() => 1;
+  b() => () => a();
+}
+main() {
+  print(new A().b()());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_11.dart b/tests/compiler/dart2js/cps_ir/input/closures_11.dart
new file mode 100644
index 0000000..cd8e049
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_11.dart
@@ -0,0 +1,6 @@
+staticMethod(x) { print(x); return x; }
+main(x) {
+  var tearOff = staticMethod;
+  print(tearOff(123));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_12.dart b/tests/compiler/dart2js/cps_ir/input/closures_12.dart
new file mode 100644
index 0000000..9e787fa
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_12.dart
@@ -0,0 +1,8 @@
+class Foo {
+  instanceMethod(x) => x;
+}
+main(x) {
+  var tearOff = new Foo().instanceMethod;
+  print(tearOff(123));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_13.dart b/tests/compiler/dart2js/cps_ir/input/closures_13.dart
new file mode 100644
index 0000000..9994ca3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_13.dart
@@ -0,0 +1,9 @@
+class Foo {
+  instanceMethod(x) => x;
+}
+main(x) {
+  var tearOff = new Foo().instanceMethod;
+  print(tearOff(123));
+  print(tearOff(321));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_14.dart b/tests/compiler/dart2js/cps_ir/input/closures_14.dart
new file mode 100644
index 0000000..5ef8e6c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_14.dart
@@ -0,0 +1,12 @@
+class Foo {
+  get getter {
+    print('getter');
+    return (x) => x;
+  }
+}
+main(x) {
+  var notTearOff = new Foo().getter;
+  print(notTearOff(123));
+  print(notTearOff(321));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_15.dart b/tests/compiler/dart2js/cps_ir/input/closures_15.dart
new file mode 100644
index 0000000..55e1263
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_15.dart
@@ -0,0 +1,11 @@
+class Foo {
+  get getter {
+    print('getter');
+    return (x) => x;
+  }
+}
+main(x) {
+  var notTearOff = new Foo().getter;
+  print(notTearOff(123));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_2.dart b/tests/compiler/dart2js/cps_ir/input/closures_2.dart
new file mode 100644
index 0000000..7c8ad36
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_2.dart
@@ -0,0 +1,9 @@
+main(x) {
+  a() {
+    return x;
+  }
+  x = x + '1';
+  print(a());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_3.dart b/tests/compiler/dart2js/cps_ir/input/closures_3.dart
new file mode 100644
index 0000000..6e4f5d9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_3.dart
@@ -0,0 +1,7 @@
+main(x) {
+  a() {
+    return x;
+  }
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_4.dart b/tests/compiler/dart2js/cps_ir/input/closures_4.dart
new file mode 100644
index 0000000..e6be22c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_4.dart
@@ -0,0 +1,8 @@
+main(x) {
+  a() {
+    return x;
+  }
+  print(a());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_5.dart b/tests/compiler/dart2js/cps_ir/input/closures_5.dart
new file mode 100644
index 0000000..3e35ec0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_5.dart
@@ -0,0 +1,7 @@
+main() {
+  var x = 122;
+  var a = () => x;
+  x = x + 1;
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_6.dart b/tests/compiler/dart2js/cps_ir/input/closures_6.dart
new file mode 100644
index 0000000..e9ff65b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_6.dart
@@ -0,0 +1,8 @@
+main() {
+  var x = 122;
+  var a = () => x;
+  x = x + 1;
+  print(a());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_7.dart b/tests/compiler/dart2js/cps_ir/input/closures_7.dart
new file mode 100644
index 0000000..05087ca
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_7.dart
@@ -0,0 +1,10 @@
+main() {
+  var x = 122;
+  var a = () {
+    var y = x;
+    return () => y;
+  };
+  x = x + 1;
+  print(a()());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_8.dart b/tests/compiler/dart2js/cps_ir/input/closures_8.dart
new file mode 100644
index 0000000..2b6e8c5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_8.dart
@@ -0,0 +1,11 @@
+main() {
+  var x = 122;
+  var a = () {
+    var y = x;
+    return () => y;
+  };
+  x = x + 1;
+  print(a()());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_9.dart b/tests/compiler/dart2js/cps_ir/input/closures_9.dart
new file mode 100644
index 0000000..185576a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_9.dart
@@ -0,0 +1,8 @@
+main() {
+  var a;
+  for (var i=0; i<10; i++) {
+    a = () => i;
+  }
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart
new file mode 100644
index 0000000..c39bc74
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart
@@ -0,0 +1,4 @@
+// Constant folding
+main() {
+  print('A'.codeUnitAt(0));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart
new file mode 100644
index 0000000..a26c359
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart
@@ -0,0 +1,10 @@
+// Bounds checking
+foo(s) {
+  var sum = 0;
+  for (int i = 0; i < s.length; i++) sum += s.codeUnitAt(i);
+  return sum;
+}
+main() {
+  print(foo('ABC'));
+  print(foo('Hello'));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_1.dart b/tests/compiler/dart2js/cps_ir/input/constructor_1.dart
new file mode 100644
index 0000000..1cc265a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_1.dart
@@ -0,0 +1,11 @@
+class Base {
+  var x;
+  Base(this.x);
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x);
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_10.dart b/tests/compiler/dart2js/cps_ir/input/constructor_10.dart
new file mode 100644
index 0000000..1e3dddc
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_10.dart
@@ -0,0 +1,11 @@
+// Method to test: generative_constructor(C#)
+class C<T> {
+  var x;
+  C() : x = new D<T>();
+}
+class D<T> {
+  foo() => T;
+}
+main() {
+  print(new C<int>().x.foo());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_11.dart b/tests/compiler/dart2js/cps_ir/input/constructor_11.dart
new file mode 100644
index 0000000..c4ee04c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_11.dart
@@ -0,0 +1,8 @@
+class A {
+  var x;
+  A() : this.b(1);
+  A.b(this.x);
+}
+main() {
+  print(new A().x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_12.dart b/tests/compiler/dart2js/cps_ir/input/constructor_12.dart
new file mode 100644
index 0000000..efafb99
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_12.dart
@@ -0,0 +1,11 @@
+class Foo {
+  factory Foo.make(x) {
+    print('Foo');
+    return new Foo.create(x);
+  }
+  var x;
+  Foo.create(this.x);
+}
+main() {
+  print(new Foo.make(5));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_13.dart b/tests/compiler/dart2js/cps_ir/input/constructor_13.dart
new file mode 100644
index 0000000..dcba070
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_13.dart
@@ -0,0 +1,8 @@
+class Foo {
+  factory Foo.make(x) = Foo.create;
+  var x;
+  Foo.create(this.x);
+}
+main() {
+  print(new Foo.make(5));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_14.dart b/tests/compiler/dart2js/cps_ir/input/constructor_14.dart
new file mode 100644
index 0000000..b22bbcb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_14.dart
@@ -0,0 +1,13 @@
+class A {
+  factory A(x) = B<int>;
+  get typevar;
+}
+class B<T> implements A {
+  var x;
+  B(this.x);
+
+  get typevar => T;
+}
+main() {
+  new A(5).typevar;
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_2.dart b/tests/compiler/dart2js/cps_ir/input/constructor_2.dart
new file mode 100644
index 0000000..23ac512
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_2.dart
@@ -0,0 +1,13 @@
+class Base {
+  var x;
+  Base(this.x);
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x) {
+    print(x);
+  }
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_3.dart b/tests/compiler/dart2js/cps_ir/input/constructor_3.dart
new file mode 100644
index 0000000..7a532a3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_3.dart
@@ -0,0 +1,18 @@
+class Base0 {
+  Base0() {
+    print('Base0');
+  }
+}
+class Base extends Base0 {
+  var x;
+  Base(this.x);
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x) {
+    print(x);
+  }
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_4.dart b/tests/compiler/dart2js/cps_ir/input/constructor_4.dart
new file mode 100644
index 0000000..5f14854
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_4.dart
@@ -0,0 +1,20 @@
+class Base0 {
+  Base0() {
+    print('Base0');
+  }
+}
+class Base extends Base0 {
+  var x;
+  Base(x1) : x = (() => ++x1) {
+    print(x1); // use boxed x1
+  }
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x) {
+    print(x);
+  }
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_5.dart b/tests/compiler/dart2js/cps_ir/input/constructor_5.dart
new file mode 100644
index 0000000..f615668
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_5.dart
@@ -0,0 +1,19 @@
+foo(x) {
+  print(x);
+}
+class Base {
+  var x1 = foo('x1');
+  var x2;
+  var x3 = foo('x3');
+  Base() : x2 = foo('x2');
+}
+class Sub extends Base {
+  var y1 = foo('y1');
+  var y2;
+  var y3;
+  Sub() : y2 = foo('y2'), super(), y3 = foo('y3');
+}
+main() {
+  new Sub();
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_6.dart b/tests/compiler/dart2js/cps_ir/input/constructor_6.dart
new file mode 100644
index 0000000..f1c6b51
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_6.dart
@@ -0,0 +1,16 @@
+class Bar {
+  Bar(x, {y, z: 'z', w: '_', q}) {
+    print(x);
+    print(y);
+    print(z);
+    print(w);
+    print(q);
+  }
+}
+class Foo extends Bar {
+  Foo() : super('x', y: 'y', w: 'w');
+}
+main() {
+  new Foo();
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_7.dart b/tests/compiler/dart2js/cps_ir/input/constructor_7.dart
new file mode 100644
index 0000000..32af53c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_7.dart
@@ -0,0 +1,6 @@
+class C<T> {
+  foo() => T;
+}
+main() {
+  print(new C<int>().foo());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_8.dart b/tests/compiler/dart2js/cps_ir/input/constructor_8.dart
new file mode 100644
index 0000000..3e72ab1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_8.dart
@@ -0,0 +1,6 @@
+class C<T> {
+  foo() => C;
+}
+main() {
+  print(new C<int>().foo());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_9.dart b/tests/compiler/dart2js/cps_ir/input/constructor_9.dart
new file mode 100644
index 0000000..fe8dfbf
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_9.dart
@@ -0,0 +1,8 @@
+// Method to test: generative_constructor(C#)
+class C<T> {
+  C() { print(T); }
+  foo() => print(T);
+}
+main() {
+  new C<int>();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart
new file mode 100644
index 0000000..72e7e7c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart
@@ -0,0 +1,4 @@
+main() {
+  while (true);
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
new file mode 100644
index 0000000..dd06bed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
@@ -0,0 +1,14 @@
+foo(a) { print(a); return a; }
+
+main() {
+  while (true) {
+    l: while (true) {
+      while (foo(true)) {
+        if (foo(false)) break l;
+      }
+      print(1);
+    }
+    print(2);
+  }
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
new file mode 100644
index 0000000..51cead4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
@@ -0,0 +1,9 @@
+foo(a) { print(a); return a; }
+
+main() {
+  for (int i = 0; foo(true); i = foo(i)) {
+    print(1);
+    if (foo(false)) break;
+  }
+  print(2);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
new file mode 100644
index 0000000..881d8ce
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
@@ -0,0 +1,11 @@
+foo(a) { print(a); return a; }
+
+main() {
+ foo(false);
+ if (foo(true)) {
+   print(1);
+ } else {
+   print(2);
+ }
+ print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
new file mode 100644
index 0000000..6efe03c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
@@ -0,0 +1,13 @@
+foo(a) { print(a); return a; }
+
+main() {
+ foo(false);
+ if (foo(true)) {
+   print(1);
+   print(1);
+ } else {
+   print(2);
+   print(2);
+ }
+ print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart
new file mode 100644
index 0000000..58550fe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart
@@ -0,0 +1,7 @@
+main() {
+  if (1) {
+    print('bad');
+  } else {
+    print('good');
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart
new file mode 100644
index 0000000..66709ff
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart
@@ -0,0 +1,8 @@
+foo() { print('2'); return 2; }
+main() {
+  if (foo()) {
+    print('bad');
+  } else {
+    print('good');
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart
new file mode 100644
index 0000000..62c6fed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart
@@ -0,0 +1,6 @@
+main() {
+  var list = [1,2,3,4,5,6];
+  for (var x in list) {
+    print(x);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart
new file mode 100644
index 0000000..7e59e5a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart
@@ -0,0 +1,8 @@
+main() {
+  var xs = ['x', 'y', 'z'], ys = ['A', 'B', 'C'];
+  var xit = xs.iterator, yit = ys.iterator;
+  while (xit.moveNext() && yit.moveNext()) {
+    print(xit.current);
+    print(yit.current);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/gvn_1.dart b/tests/compiler/dart2js/cps_ir/input/gvn_1.dart
new file mode 100644
index 0000000..4953cb9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/gvn_1.dart
@@ -0,0 +1,41 @@
+foo(x, list) {
+  var sum = 0;
+  for (int k = 0; k < 10; k++) {
+    // Everything can be hoisted out up to the index access which is
+    // blocked by the bounds check.
+    var a = x.left.left;
+    var b = x.left.right;
+    var c = x.right.left;
+    var d = x.right.right;
+    var i = a.value + c.value;
+    var j = b.value + d.value;
+    var z = list[i * j] + i;
+    sum += z;
+  }
+  return sum;
+}
+// Use a different class for each level in the tree, so type inference
+// is not confused.
+class Root {
+  Branch left, right;
+  Root(this.left, this.right);
+}
+class Branch {
+  Leaf left, right;
+  Branch(this.left, this.right);
+}
+class Leaf {
+  int value;
+  Leaf(this.value);
+}
+main() {
+  var x1 = new Leaf(1);
+  var x2 = new Leaf(10);
+  var x3 = new Leaf(20);
+  var x4 = new Leaf(-10);
+  var y1 = new Branch(x1, x2);
+  var y2 = new Branch(x3, x4);
+  var z  = new Root(y1, y2);
+  print(foo(z, [1,2,3,4,5,6,7,8,9,10]));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart b/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart
new file mode 100644
index 0000000..6363521
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart
@@ -0,0 +1,6 @@
+main() {
+  var g = 1;
+
+  var x = g + 3;
+  print(x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart b/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart
new file mode 100644
index 0000000..7853486
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart
@@ -0,0 +1,10 @@
+main() {
+  var l = ['hest', ['h', 'e', 's', 't']];
+  print(l.length);
+  for (int i  = 0; i < l.length; i++) {
+    var x = l[i];
+    for (int j = 0; j < x.length; j++) {
+      print(x[j]);
+    }
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/literals_1.dart b/tests/compiler/dart2js/cps_ir/input/literals_1.dart
new file mode 100644
index 0000000..a5d7294
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/literals_1.dart
@@ -0,0 +1,10 @@
+main() {
+  print([]);
+  print([1]);
+  print([1, 2]);
+  print([1, [1, 2]]);
+  print({});
+  print({1: 2});
+  print({[1, 2]: [3, 4]});
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_1.dart b/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
new file mode 100644
index 0000000..05da19c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
@@ -0,0 +1,5 @@
+foo(a, b) => ((a & 0xff0000) >> 1) & b;
+main() {
+  print(foo(123, 234));
+  print(foo(0, 2));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_2.dart b/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
new file mode 100644
index 0000000..56bebd9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
@@ -0,0 +1,5 @@
+foo(a) => ~a;
+main() {
+  print(foo(1));
+  print(foo(10));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_3.dart b/tests/compiler/dart2js/cps_ir/input/operators2_3.dart
new file mode 100644
index 0000000..f1dc5ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_3.dart
@@ -0,0 +1,6 @@
+// Method to test: function(foo)
+foo(a) => a % 13;
+main() {
+  print(foo(5));
+  print(foo(-100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_4.dart b/tests/compiler/dart2js/cps_ir/input/operators2_4.dart
new file mode 100644
index 0000000..b9f5be2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_4.dart
@@ -0,0 +1,5 @@
+foo(a) => a % 13;
+main() {
+  print(foo(5));
+  print(foo(100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_5.dart b/tests/compiler/dart2js/cps_ir/input/operators2_5.dart
new file mode 100644
index 0000000..3ece837
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_5.dart
@@ -0,0 +1,5 @@
+foo(a) => a.remainder(13);
+main() {
+  print(foo(5));
+  print(foo(-100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_6.dart b/tests/compiler/dart2js/cps_ir/input/operators2_6.dart
new file mode 100644
index 0000000..4b763a6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_6.dart
@@ -0,0 +1,6 @@
+// Method to test: function(foo)
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(-100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_7.dart b/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
new file mode 100644
index 0000000..f2c68ee
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
@@ -0,0 +1,5 @@
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_8.dart b/tests/compiler/dart2js/cps_ir/input/operators2_8.dart
new file mode 100644
index 0000000..05e3bb0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_8.dart
@@ -0,0 +1,6 @@
+// Method to test: function(foo)
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(8000000000));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_1.dart b/tests/compiler/dart2js/cps_ir/input/operators_1.dart
new file mode 100644
index 0000000..52e587e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_1.dart
@@ -0,0 +1 @@
+main() { return true ? 42 : 'foo'; }
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_2.dart b/tests/compiler/dart2js/cps_ir/input/operators_2.dart
new file mode 100644
index 0000000..c9049ed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_2.dart
@@ -0,0 +1,5 @@
+var x = 1;
+foo() => ++x > 10;
+main() {
+  print(foo() ? "hello world" : "bad bad");
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_3.dart b/tests/compiler/dart2js/cps_ir/input/operators_3.dart
new file mode 100644
index 0000000..42ceb0e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_3.dart
@@ -0,0 +1,5 @@
+var x = 1;
+get foo => ++x > 10;
+main() {
+  print(foo ? "hello world" : "bad bad");
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_4.dart b/tests/compiler/dart2js/cps_ir/input/operators_4.dart
new file mode 100644
index 0000000..3f07752
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_4.dart
@@ -0,0 +1,4 @@
+var x = 1;
+get foo => ++x > 10;
+main() { print(foo && foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_5.dart b/tests/compiler/dart2js/cps_ir/input/operators_5.dart
new file mode 100644
index 0000000..98756b6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_5.dart
@@ -0,0 +1,4 @@
+var x = 1;
+get foo => ++x > 10;
+main() { print(foo || foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_6.dart b/tests/compiler/dart2js/cps_ir/input/operators_6.dart
new file mode 100644
index 0000000..36e7d9f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_6.dart
@@ -0,0 +1,3 @@
+get foo => foo;
+main() { print(foo || foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_7.dart b/tests/compiler/dart2js/cps_ir/input/operators_7.dart
new file mode 100644
index 0000000..8838126
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_7.dart
@@ -0,0 +1,9 @@
+class Foo {
+  operator[]=(index, value) {
+    print(value);
+  }
+}
+main() {
+  var foo = new Foo();
+  foo[5] = 6;
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_8.dart b/tests/compiler/dart2js/cps_ir/input/operators_8.dart
new file mode 100644
index 0000000..c5b66d3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_8.dart
@@ -0,0 +1,5 @@
+main() {
+  var list = [1, 2, 3];
+  list[1] = 6;
+  print(list);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart
new file mode 100644
index 0000000..f67e4d3a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart
@@ -0,0 +1,7 @@
+class C<T> {
+  foo() => print(T);
+}
+
+main() {
+  new C<int>().foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart
new file mode 100644
index 0000000..a225509
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart
@@ -0,0 +1,9 @@
+class C<T, U> {
+  foo() => print(U);
+}
+
+class D extends C<int, double> {}
+
+main() {
+  new D().foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart
new file mode 100644
index 0000000..c9253bb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart
@@ -0,0 +1,9 @@
+class C<T> {
+  foo() => new D<C<T>>();
+}
+class D<T> {
+  bar() => T;
+}
+main() {
+  print(new C<int>().foo().bar());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart
new file mode 100644
index 0000000..f45e59c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart
@@ -0,0 +1,7 @@
+// Method to test: generative_constructor(C#)
+class C<X, Y, Z> {
+  foo() => 'C<$X $Y, $Z>';
+}
+main() {
+  new C<C, int, String>().foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_1.dart b/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
new file mode 100644
index 0000000..04d5817
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
@@ -0,0 +1,11 @@
+class Base {
+  m(x) {
+    print(x+1);
+  }
+}
+class Sub extends Base {
+  m(x) => super.m(x+10);
+}
+main() {
+  new Sub().m(100);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_2.dart b/tests/compiler/dart2js/cps_ir/input/supercall_2.dart
new file mode 100644
index 0000000..1a2f726
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_2.dart
@@ -0,0 +1,23 @@
+// TODO(sigmund): change this to check method "function(Sub#+)" once we provide
+// a way to disable inlining of Sub#+, which is compiled to something like:
+// function(x) {
+//   var v0, v1, v2;
+//   v0 = 1;
+//   v1 = J.getInterceptor$ns(x).$add(x, v0);
+//   v2 = this;
+//   return V.Base.prototype.$add.call(null, v2, v1);
+// }
+
+class Base {
+  m(x) {
+    print(x+1000);
+  }
+  operator+(x) => m(x+10);
+}
+class Sub extends Base {
+  m(x) => super.m(x+100);
+  operator+(x) => super + (x+1);
+}
+main() {
+  new Sub() + 10000;
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_3.dart b/tests/compiler/dart2js/cps_ir/input/supercall_3.dart
new file mode 100644
index 0000000..dd2edfc
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_3.dart
@@ -0,0 +1,9 @@
+class Base {
+  var field = 123;
+}
+class Sub extends Base {
+  m(x) => x + super.field;
+}
+main() {
+  print(new Sub().m(10));
+}
diff --git a/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart b/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart
new file mode 100644
index 0000000..98d813a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.interceptors_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("interceptors_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart b/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart
new file mode 100644
index 0000000..2562d63
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.interceptors_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("interceptors_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/literals_1_test.dart b/tests/compiler/dart2js/cps_ir/literals_1_test.dart
new file mode 100644
index 0000000..86e1f1d5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/literals_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.literals_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("literals_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_1_test.dart b/tests/compiler/dart2js/cps_ir/operators2_1_test.dart
new file mode 100644
index 0000000..acf42c2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_2_test.dart b/tests/compiler/dart2js/cps_ir/operators2_2_test.dart
new file mode 100644
index 0000000..75f6bb7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_3_test.dart b/tests/compiler/dart2js/cps_ir/operators2_3_test.dart
new file mode 100644
index 0000000..7fc2f50
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_4_test.dart b/tests/compiler/dart2js/cps_ir/operators2_4_test.dart
new file mode 100644
index 0000000..9315168
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_5_test.dart b/tests/compiler/dart2js/cps_ir/operators2_5_test.dart
new file mode 100644
index 0000000..03544c1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_6_test.dart b/tests/compiler/dart2js/cps_ir/operators2_6_test.dart
new file mode 100644
index 0000000..e11bd8a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_7_test.dart b/tests/compiler/dart2js/cps_ir/operators2_7_test.dart
new file mode 100644
index 0000000..13480a4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_8_test.dart b/tests/compiler/dart2js/cps_ir/operators2_8_test.dart
new file mode 100644
index 0000000..d39aa5f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_1_test.dart b/tests/compiler/dart2js/cps_ir/operators_1_test.dart
new file mode 100644
index 0000000..9e457ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_2_test.dart b/tests/compiler/dart2js/cps_ir/operators_2_test.dart
new file mode 100644
index 0000000..99dd439
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_3_test.dart b/tests/compiler/dart2js/cps_ir/operators_3_test.dart
new file mode 100644
index 0000000..57ebc5a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_4_test.dart b/tests/compiler/dart2js/cps_ir/operators_4_test.dart
new file mode 100644
index 0000000..c7fed55
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_5_test.dart b/tests/compiler/dart2js/cps_ir/operators_5_test.dart
new file mode 100644
index 0000000..c412522
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_6_test.dart b/tests/compiler/dart2js/cps_ir/operators_6_test.dart
new file mode 100644
index 0000000..01246e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_7_test.dart b/tests/compiler/dart2js/cps_ir/operators_7_test.dart
new file mode 100644
index 0000000..2864e6f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_8_test.dart b/tests/compiler/dart2js/cps_ir/operators_8_test.dart
new file mode 100644
index 0000000..6c2d67c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runner.dart b/tests/compiler/dart2js/cps_ir/runner.dart
new file mode 100644
index 0000000..a71bd9a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runner.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2016, 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.
+
+// Test that the CPS IR code generator compiles programs and produces the
+// the expected output.
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/apiimpl.dart' show
+    CompilerImpl;
+import '../memory_compiler.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/elements/elements.dart' show
+    ClassElement,
+    Element;
+
+// Regular experession used to extract the method name that is used to match the
+// test output. By default we match the output of main.
+final RegExp elementNameRegExp = new RegExp(r'^// Method to test: (.*)$',
+    multiLine: true);
+
+runTest(String filename, {bool update: false}) {
+  var outputname = filename.replaceFirst('.dart', '.js');
+  String source = new File.fromUri(Platform.script.resolve('input/$filename'))
+      .readAsStringSync();
+  var expectedFile =
+      new File.fromUri(Platform.script.resolve('expected/$outputname'));
+  String expected = expectedFile.existsSync()
+    ? expectedFile.readAsStringSync() : '';
+  var match = elementNameRegExp.firstMatch(source);
+  var elementName = match?.group(1);
+
+  Map files = {TEST_MAIN_FILE: source};
+  asyncTest(() async {
+    Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
+    String found = null;
+    try {
+      CompilationResult result = await runCompiler(
+          entryPoint: uri,
+          memorySourceFiles: files,
+          options: <String>['--use-cps-ir']);
+      Expect.isTrue(result.isSuccess);
+      CompilerImpl compiler = result.compiler;
+      if (expected != null) {
+        String output = elementName == null
+            ? _getCodeForMain(compiler)
+            : _getCodeForMethod(compiler, elementName);
+        // Include the input in a comment of the expected file to make it easier
+        // to see the relation between input and output in code reviews.
+        found = '// Expectation for test: \n'
+            '// ${source.trim().replaceAll('\n', '\n// ')}\n\n'
+            '$output\n';
+      }
+    } catch (e, st) {
+      print(e);
+      print(st);
+      var message = 'The following test failed to compile:\n'
+                    '${_formatTest(files)}';
+      if (update) {
+        print('\n\n$message\n');
+        return;
+      } else {
+        Expect.fail(message);
+      }
+    }
+    if (expected != found) {
+      if (update) {
+        expectedFile.writeAsStringSync(found);
+        print('INFO: $expectedFile was updated');
+      } else {
+        Expect.fail('Unexpected output for test:\n  '
+            '${_formatTest(files).replaceAll('\n', '\n  ')}\n'
+            'Expected:\n  ${expected.replaceAll('\n', '\n  ')}\n'
+            'but found:\n  ${found?.replaceAll('\n', '\n  ')}\n'
+            '$regenerateCommand');
+      }
+    }
+  });
+}
+
+String get regenerateCommand {
+  var flags = Platform.packageRoot == null
+    ? '' : '--package-root=${Platform.packageRoot} ';
+  return '''
+If you wish to update the test expectations, rerun this test passing "update" as
+an argument, as follows:
+
+  dart $flags${Platform.script} update
+
+If you want to update more than one test at once, run:
+  dart $flags${Platform.script.resolve('update_all.dart')}
+
+''';
+}
+
+const String TEST_MAIN_FILE = 'test.dart';
+
+String _formatTest(Map test) {
+  return test[TEST_MAIN_FILE];
+}
+
+String _getCodeForMain(CompilerImpl compiler) {
+  Element mainFunction = compiler.mainFunction;
+  js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
+  return js.prettyPrint(ast, compiler).getText();
+}
+
+String _getCodeForMethod(CompilerImpl compiler,
+                        String name) {
+  Element foundElement;
+  for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
+    if (element.toString() == name) {
+      if (foundElement != null) {
+        Expect.fail('Multiple compiled elements are called $name');
+      }
+      foundElement = element;
+    }
+  }
+
+  if (foundElement == null) {
+    Expect.fail('There is no compiled element called $name');
+  }
+
+  js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
+  return js.prettyPrint(ast, compiler).getText();
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart
new file mode 100644
index 0000000..f5336f1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart
new file mode 100644
index 0000000..978f612
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart
new file mode 100644
index 0000000..43a3349
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart
new file mode 100644
index 0000000..eaf7937
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/supercall_1_test.dart b/tests/compiler/dart2js/cps_ir/supercall_1_test.dart
new file mode 100644
index 0000000..caf3030
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/supercall_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.supercall_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("supercall_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/supercall_2_test.dart b/tests/compiler/dart2js/cps_ir/supercall_2_test.dart
new file mode 100644
index 0000000..6f40662
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/supercall_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.supercall_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("supercall_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/supercall_3_test.dart b/tests/compiler/dart2js/cps_ir/supercall_3_test.dart
new file mode 100644
index 0000000..9b96977
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/supercall_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.supercall_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("supercall_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/up_to_date_test.dart b/tests/compiler/dart2js/cps_ir/up_to_date_test.dart
new file mode 100644
index 0000000..a9508a4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/up_to_date_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2016, 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.
+
+/// Test that cps_ir/update_all.dart and every cps_ir/*_test.dart file are up to
+/// date. There should be a line in update_all and a file in the cps_ir folder
+/// for each test file in the `input/` folder.
+library tests.compiler.dart2js.cps_ir.up_to_date_test;
+
+import 'dart:io';
+
+main(args) {
+  bool update = args.length > 0 && args[0] == 'update';
+  var inputDir = new Directory.fromUri(Platform.script.resolve('input'));
+
+  bool errorsFound = false;
+
+  // Note: we create a test file per input file because invoking dart2js many
+  // times on a single test often makes test.py timeout.
+  //
+  // We tried using multi-tests for this, but it is unfortunately brittle. For
+  // example, multi-tests can't import code from one folder above the current
+  // directory, which prevents us from putting generated tests under a different
+  // folder than the rest of the helpers (like memory_compiler.dart)
+  var files = inputDir.listSync().map((f) => f.uri.pathSegments.last).toList();
+  files.sort();
+  for (var file in files) {
+    var testFilename = file.replaceAll('.dart', '_test.dart');
+    var contents = generateTestFile(file);
+    if (checkAndMaybeUpdate(testFilename, contents, update)) errorsFound = true;
+  }
+
+  var updateAllContents = generateUpdateAllFile(files);
+  if (checkAndMaybeUpdate('update_all.dart', updateAllContents, update)) {
+    errorsFound = true;
+  }
+
+  if (errorsFound) {
+    print(regenerateMessage);
+    exit(1);
+  }
+}
+
+/// Checks and if [update] is true, updates an autogenerated test file.
+///
+/// This doesn't update an actual test expectation, that's done by executing the
+/// files that we generate here.
+bool checkAndMaybeUpdate(String filename, String contents,
+    bool update) {
+  var testFile = new File.fromUri(Platform.script.resolve(filename));
+  bool exists = testFile.existsSync();
+  var isUpToDate = exists && testFile.readAsStringSync() == contents;
+  if (isUpToDate) {
+    print('PASS: ${filename} is up to date.');
+  } else if (update) {
+    testFile.writeAsStringSync(contents);
+    print('INFO: ${filename} was updated.');
+  } else {
+    print("FAILED: ${filename} is ${exists ? 'out of date' : 'missing'}");
+    return true;
+  }
+  return false;
+}
+
+String generateUpdateAllFile(List<String> files) {
+  var lines = files.map((f) => "runTest('$f', update: true);");
+  return '''
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/${Platform.script.pathSegments.last} update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.update_all;
+
+import 'runner.dart';
+
+main(args) {
+  ${lines.join('\n  ')}
+}
+''';
+}
+
+String generateTestFile(String file) => '''
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/${Platform.script.pathSegments.last} update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.$file;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("$file", update: args.length > 0 && args[0] == "update");
+}
+''';
+
+
+String get regenerateMessage {
+  var flags = Platform.packageRoot == null
+    ? '' : '--package-root=${Platform.packageRoot} ';
+  return '''
+
+To regenerate the test files, please run:
+  dart $flags${Platform.script} update''';
+}
diff --git a/tests/compiler/dart2js/cps_ir/update_all.dart b/tests/compiler/dart2js/cps_ir/update_all.dart
new file mode 100644
index 0000000..726f2e4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/update_all.dart
@@ -0,0 +1,142 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.update_all;
+
+import 'runner.dart';
+
+main(args) {
+  runTest('argument_refinement_1.dart', update: true);
+  runTest('argument_refinement_10.dart', update: true);
+  runTest('argument_refinement_11.dart', update: true);
+  runTest('argument_refinement_12.dart', update: true);
+  runTest('argument_refinement_13.dart', update: true);
+  runTest('argument_refinement_14.dart', update: true);
+  runTest('argument_refinement_15.dart', update: true);
+  runTest('argument_refinement_16.dart', update: true);
+  runTest('argument_refinement_17.dart', update: true);
+  runTest('argument_refinement_18.dart', update: true);
+  runTest('argument_refinement_19.dart', update: true);
+  runTest('argument_refinement_2.dart', update: true);
+  runTest('argument_refinement_20.dart', update: true);
+  runTest('argument_refinement_21.dart', update: true);
+  runTest('argument_refinement_22.dart', update: true);
+  runTest('argument_refinement_23.dart', update: true);
+  runTest('argument_refinement_24.dart', update: true);
+  runTest('argument_refinement_25.dart', update: true);
+  runTest('argument_refinement_26.dart', update: true);
+  runTest('argument_refinement_27.dart', update: true);
+  runTest('argument_refinement_28.dart', update: true);
+  runTest('argument_refinement_3.dart', update: true);
+  runTest('argument_refinement_4.dart', update: true);
+  runTest('argument_refinement_5.dart', update: true);
+  runTest('argument_refinement_6.dart', update: true);
+  runTest('argument_refinement_7.dart', update: true);
+  runTest('argument_refinement_8.dart', update: true);
+  runTest('argument_refinement_9.dart', update: true);
+  runTest('argument_refinement_num_1.dart', update: true);
+  runTest('argument_refinement_num_10.dart', update: true);
+  runTest('argument_refinement_num_11.dart', update: true);
+  runTest('argument_refinement_num_12.dart', update: true);
+  runTest('argument_refinement_num_13.dart', update: true);
+  runTest('argument_refinement_num_14.dart', update: true);
+  runTest('argument_refinement_num_15.dart', update: true);
+  runTest('argument_refinement_num_16.dart', update: true);
+  runTest('argument_refinement_num_17.dart', update: true);
+  runTest('argument_refinement_num_2.dart', update: true);
+  runTest('argument_refinement_num_3.dart', update: true);
+  runTest('argument_refinement_num_4.dart', update: true);
+  runTest('argument_refinement_num_5.dart', update: true);
+  runTest('argument_refinement_num_6.dart', update: true);
+  runTest('argument_refinement_num_7.dart', update: true);
+  runTest('argument_refinement_num_8.dart', update: true);
+  runTest('argument_refinement_num_9.dart', update: true);
+  runTest('basic_1.dart', update: true);
+  runTest('basic_10.dart', update: true);
+  runTest('basic_11.dart', update: true);
+  runTest('basic_12.dart', update: true);
+  runTest('basic_13.dart', update: true);
+  runTest('basic_14.dart', update: true);
+  runTest('basic_15.dart', update: true);
+  runTest('basic_16.dart', update: true);
+  runTest('basic_2.dart', update: true);
+  runTest('basic_3.dart', update: true);
+  runTest('basic_4.dart', update: true);
+  runTest('basic_5.dart', update: true);
+  runTest('basic_6.dart', update: true);
+  runTest('basic_7.dart', update: true);
+  runTest('basic_8.dart', update: true);
+  runTest('basic_9.dart', update: true);
+  runTest('closures_1.dart', update: true);
+  runTest('closures_10.dart', update: true);
+  runTest('closures_11.dart', update: true);
+  runTest('closures_12.dart', update: true);
+  runTest('closures_13.dart', update: true);
+  runTest('closures_14.dart', update: true);
+  runTest('closures_15.dart', update: true);
+  runTest('closures_2.dart', update: true);
+  runTest('closures_3.dart', update: true);
+  runTest('closures_4.dart', update: true);
+  runTest('closures_5.dart', update: true);
+  runTest('closures_6.dart', update: true);
+  runTest('closures_7.dart', update: true);
+  runTest('closures_8.dart', update: true);
+  runTest('closures_9.dart', update: true);
+  runTest('codeUnitAt_1.dart', update: true);
+  runTest('codeUnitAt_2.dart', update: true);
+  runTest('constructor_1.dart', update: true);
+  runTest('constructor_10.dart', update: true);
+  runTest('constructor_11.dart', update: true);
+  runTest('constructor_12.dart', update: true);
+  runTest('constructor_13.dart', update: true);
+  runTest('constructor_14.dart', update: true);
+  runTest('constructor_2.dart', update: true);
+  runTest('constructor_3.dart', update: true);
+  runTest('constructor_4.dart', update: true);
+  runTest('constructor_5.dart', update: true);
+  runTest('constructor_6.dart', update: true);
+  runTest('constructor_7.dart', update: true);
+  runTest('constructor_8.dart', update: true);
+  runTest('constructor_9.dart', update: true);
+  runTest('control_flow_1.dart', update: true);
+  runTest('control_flow_2.dart', update: true);
+  runTest('control_flow_3.dart', update: true);
+  runTest('control_flow_4.dart', update: true);
+  runTest('control_flow_5.dart', update: true);
+  runTest('control_flow_6.dart', update: true);
+  runTest('control_flow_7.dart', update: true);
+  runTest('control_flow_8.dart', update: true);
+  runTest('control_flow_9.dart', update: true);
+  runTest('gvn_1.dart', update: true);
+  runTest('interceptors_1.dart', update: true);
+  runTest('interceptors_2.dart', update: true);
+  runTest('literals_1.dart', update: true);
+  runTest('operators2_1.dart', update: true);
+  runTest('operators2_2.dart', update: true);
+  runTest('operators2_3.dart', update: true);
+  runTest('operators2_4.dart', update: true);
+  runTest('operators2_5.dart', update: true);
+  runTest('operators2_6.dart', update: true);
+  runTest('operators2_7.dart', update: true);
+  runTest('operators2_8.dart', update: true);
+  runTest('operators_1.dart', update: true);
+  runTest('operators_2.dart', update: true);
+  runTest('operators_3.dart', update: true);
+  runTest('operators_4.dart', update: true);
+  runTest('operators_5.dart', update: true);
+  runTest('operators_6.dart', update: true);
+  runTest('operators_7.dart', update: true);
+  runTest('operators_8.dart', update: true);
+  runTest('runtime_types_1.dart', update: true);
+  runTest('runtime_types_2.dart', update: true);
+  runTest('runtime_types_3.dart', update: true);
+  runTest('runtime_types_4.dart', update: true);
+  runTest('supercall_1.dart', update: true);
+  runTest('supercall_2.dart', update: true);
+  runTest('supercall_3.dart', update: true);
+}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 70a2a3a..3d0330e 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -47,11 +47,6 @@
 backend_dart/opt_shrinking_test: Skip
 backend_dart/opt_redundant_phi_test: Skip
 
-# These tests run the compiler multiple times.
-js_backend_cps_ir_basic_test: Pass, Slow
-js_backend_cps_ir_closures_test: Pass, Slow
-js_backend_cps_ir_constructor_test: Pass, Slow
-
 # Source information is not correct due to inlining.
 js_backend_cps_ir_source_information_test: Fail
 sourcemaps/source_mapping_operators_test: Fail # Issue 25304 for checked mode, was: Pass, Slow
diff --git a/tests/compiler/dart2js/diagnostic_helper.dart b/tests/compiler/dart2js/diagnostic_helper.dart
index 2fbdfcd5..26dac30 100644
--- a/tests/compiler/dart2js/diagnostic_helper.dart
+++ b/tests/compiler/dart2js/diagnostic_helper.dart
@@ -27,7 +27,10 @@
 
   MessageKind get messageKind => message.kind;
 
-  String toString() => '${message.kind}:$uri:$begin:$end:$text:$kind';
+  String toString() {
+    return '${message != null ? message.kind : ''}'
+           ':$uri:$begin:$end:$text:$kind';
+  }
 }
 
 class DiagnosticCollector implements CompilerDiagnostics {
@@ -77,6 +80,48 @@
   void clear() {
     messages.clear();
   }
+
+  void checkMessages(List<Expected> expectedMessages) {
+    int index = 0;
+    Iterable<CollectedMessage> messages =
+        filterMessagesByKinds(
+            [Diagnostic.ERROR,
+             Diagnostic.WARNING,
+             Diagnostic.HINT,
+             Diagnostic.INFO]);
+    for (CollectedMessage message in messages) {
+      if (index >= expectedMessages.length) {
+        Expect.fail("Unexpected messages:\n "
+                    "${messages.skip(index).join('\n ')}");
+      } else {
+        Expected expected = expectedMessages[index];
+        Expect.equals(expected.messageKind, message.messageKind,
+            "Unexpected message kind in:\n ${messages.join('\n ')}");
+        Expect.equals(expected.diagnosticKind, message.kind,
+            "Unexpected diagnostic kind in\n ${messages.join('\n ')}");
+        index++;
+      }
+    }
+  }
+}
+
+class Expected {
+  final MessageKind messageKind;
+  final Diagnostic diagnosticKind;
+
+  const Expected(this.messageKind, this.diagnosticKind);
+
+  const Expected.error(MessageKind messageKind)
+      : this(messageKind, Diagnostic.ERROR);
+
+  const Expected.warning(MessageKind messageKind)
+      : this(messageKind, Diagnostic.WARNING);
+
+  const Expected.hint(MessageKind messageKind)
+      : this(messageKind, Diagnostic.HINT);
+
+  const Expected.info(MessageKind messageKind)
+      : this(messageKind, Diagnostic.INFO);
 }
 
 
diff --git a/tests/compiler/dart2js/embedded_category_api_boundary_test.dart b/tests/compiler/dart2js/embedded_category_api_boundary_test.dart
index cbd973e..76db27b 100644
--- a/tests/compiler/dart2js/embedded_category_api_boundary_test.dart
+++ b/tests/compiler/dart2js/embedded_category_api_boundary_test.dart
@@ -24,7 +24,8 @@
   });
   asyncTest(() async {
     analyze(uriList, {},
-        checkResults: checkResults, analyzeMain: true, analyzeAll: false);
+        checkResults: checkResults,
+        mode: AnalysisMode.MAIN);
   });
 }
 
diff --git a/tests/compiler/dart2js/enumset_test.dart b/tests/compiler/dart2js/enumset_test.dart
new file mode 100644
index 0000000..66fad2e
--- /dev/null
+++ b/tests/compiler/dart2js/enumset_test.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2016, 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 enumset.test;
+
+import 'package:compiler/src/util/enumset.dart';
+import 'package:expect/expect.dart';
+
+enum Enum { A, B, C, D, E, F, }
+
+main() {
+  testAddRemoveContains();
+  testConstructorsIntersects();
+}
+
+
+void checkEnumSet(EnumSet<Enum> enumSet,
+                 int expectedValue,
+                 List<Enum> expectedValues,
+                 String expectedToString) {
+  Expect.equals(expectedValue, enumSet.value,
+      "Unexpected EnumSet.value for ${enumSet.iterable(Enum.values)}");
+  Expect.listEquals(expectedValues, enumSet.iterable(Enum.values).toList(),
+      "Unexpected values: ${enumSet.iterable(Enum.values)}");
+  Expect.equals(expectedValues.isEmpty, enumSet.isEmpty,
+      "Unexpected EnumSet.isEmpty for ${enumSet.iterable(Enum.values)}");
+  Expect.equals(expectedToString, enumSet.toString(),
+      "Unexpected EnumSet.toString for ${enumSet.iterable(Enum.values)}");
+  for (Enum value in Enum.values) {
+    Expect.equals(expectedValues.contains(value), enumSet.contains(value),
+        "Unexpected EnumSet.contains for $value in "
+        "${enumSet.iterable(Enum.values)}");
+  }
+}
+
+void testAddRemoveContains() {
+  EnumSet<Enum> enumSet = new EnumSet<Enum>();
+
+  void check(int expectedValue,
+             List<Enum> expectedValues,
+             String expectedToString) {
+    checkEnumSet(enumSet, expectedValue, expectedValues, expectedToString);
+  }
+
+  check(0, [], '0');
+
+  enumSet.add(Enum.B);
+  check(2, [Enum.B], '10');
+
+  enumSet.add(Enum.F);
+  check(34, [Enum.F, Enum.B], '100010');
+
+  enumSet.add(Enum.A);
+  check(35, [Enum.F, Enum.B, Enum.A], '100011');
+
+  enumSet.add(Enum.A);
+  check(35, [Enum.F, Enum.B, Enum.A], '100011');
+
+  enumSet.remove(Enum.C);
+  check(35, [Enum.F, Enum.B, Enum.A], '100011');
+
+  enumSet.remove(Enum.B);
+  check(33, [Enum.F, Enum.A], '100001');
+
+  enumSet.remove(Enum.A);
+  check(32, [Enum.F], '100000');
+
+  enumSet.clear();
+  check(0, [], '0');
+
+  enumSet.add(Enum.A);
+  enumSet.add(Enum.B);
+  enumSet.add(Enum.C);
+  enumSet.add(Enum.D);
+  enumSet.add(Enum.E);
+  enumSet.add(Enum.F);
+  check(63, [Enum.F, Enum.E, Enum.D, Enum.C, Enum.B, Enum.A], '111111');
+}
+
+void testConstructorsIntersects() {
+  EnumSet<Enum> emptyA = new EnumSet<Enum>();
+  EnumSet<Enum> emptyB = new EnumSet<Enum>.fromValue(0);
+  EnumSet<Enum> emptyC = const EnumSet<Enum>.fixed(0);
+  EnumSet<Enum> emptyD = new EnumSet<Enum>.fixed(0);
+
+
+  void checkIntersects(EnumSet<Enum> a, EnumSet<Enum> b, bool expectedValue) {
+    Expect.equals(expectedValue, a.intersects(b),
+        "Unexpected intersects of $a and $b");
+    Expect.equals(a.intersects(b), b.intersects(a),
+        "Unsymmetric intersects of $a and $b");
+  }
+
+  void check(EnumSet<Enum> a, EnumSet<Enum> b) {
+    Expect.equals(a.value, b.value,
+        "Unexpected values of $a and $b");
+    Expect.equals(a.hashCode, b.hashCode,
+        "Unexpected hash codes of $a and $b");
+    Expect.equals(a, b,
+        "Unexpected equality of $a and $b");
+    checkIntersects(a, b, !a.isEmpty);
+  }
+
+  check(emptyA, emptyA);
+  check(emptyA, emptyB);
+  check(emptyA, emptyC);
+  check(emptyA, emptyD);
+
+  EnumSet<Enum> singleA = new EnumSet<Enum>()..add(Enum.C);
+  EnumSet<Enum> singleB = new EnumSet<Enum>.fromValue(4);
+  EnumSet<Enum> singleC = const EnumSet<Enum>.fixed(4);
+  EnumSet<Enum> singleD = new EnumSet<Enum>.fixed(4);
+  EnumSet<Enum> singleE = new EnumSet<Enum>.fromValues([Enum.C]);
+  EnumSet<Enum> singleF = new EnumSet<Enum>.fromValues([Enum.C], fixed: true);
+
+  check(singleA, singleA);
+  check(singleA, singleB);
+  check(singleA, singleC);
+  check(singleA, singleD);
+  check(singleA, singleE);
+  check(singleA, singleF);
+
+  EnumSet<Enum> multiA = new EnumSet<Enum>()
+      ..add(Enum.A)..add(Enum.D)..add(Enum.F);
+  EnumSet<Enum> multiB = new EnumSet<Enum>.fromValue(41);
+  EnumSet<Enum> multiC = const EnumSet<Enum>.fixed(41);
+  EnumSet<Enum> multiD = new EnumSet<Enum>.fixed(41);
+  EnumSet<Enum> multiE = new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.D]);
+  EnumSet<Enum> multiF =
+      new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.D], fixed: true);
+
+  check(multiA, multiA);
+  check(multiA, multiB);
+  check(multiA, multiC);
+  check(multiA, multiD);
+  check(multiA, multiE);
+  check(multiA, multiF);
+
+  EnumSet<Enum> multi2 = new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.C]);
+
+  checkIntersects(emptyA, singleA, false);
+  checkIntersects(emptyA, multiA, false);
+  checkIntersects(emptyA, multi2, false);
+
+  checkIntersects(singleA, multiA, false);
+  checkIntersects(singleA, multi2, true);
+
+  checkIntersects(multiA, multi2, true);
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/flatten_test.dart b/tests/compiler/dart2js/flatten_test.dart
index cc28c2f..0275ee7 100644
--- a/tests/compiler/dart2js/flatten_test.dart
+++ b/tests/compiler/dart2js/flatten_test.dart
@@ -2,7 +2,7 @@
 // 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 subtype_test;
+library flatten_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
index 7ceb6a1..cb9e4c8 100644
--- a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
+++ b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
@@ -35,7 +35,7 @@
     String name = 'foo';
     var element = cls.lookupLocalMember(name);
     Expect.isNotNull(element);
-    Selector selector = new Selector.getter(name, null);
+    Selector selector = new Selector.getter(new PublicName(name));
     Expect.isFalse(compiler.world.hasAnyUserDefinedGetter(selector, null));
   }));
 }
diff --git a/tests/compiler/dart2js/import_mirrors_test.dart b/tests/compiler/dart2js/import_mirrors_test.dart
index 514bedb..9c42114 100644
--- a/tests/compiler/dart2js/import_mirrors_test.dart
+++ b/tests/compiler/dart2js/import_mirrors_test.dart
@@ -5,7 +5,7 @@
 // Test that the compiler emits a warning on import of 'dart:mirrors' unless
 // the flag --enable-experimental-mirrors is used.
 
-library dart2js.test.import;
+library dart2js.test.import_mirrors;
 
 import 'dart:async';
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/import_test.dart b/tests/compiler/dart2js/import_test.dart
index ddd4992..0fbe10e 100644
--- a/tests/compiler/dart2js/import_test.dart
+++ b/tests/compiler/dart2js/import_test.dart
@@ -9,6 +9,8 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:compiler/compiler.dart';
 import 'memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
@@ -26,15 +28,55 @@
   int i = "";
 }
 ''',
+    'part.dart': '''
+part of lib;
+
+main() {}
+''',
+    'lib.dart': '''
+library lib;
+
+import 'part.dart';
+
+part 'part.dart';
+''',
 };
 
+testEntryPointIsPart() async {
+  var collector = new DiagnosticCollector();
+  await runCompiler(
+      entryPoint: Uri.parse('memory:part.dart'),
+      memorySourceFiles: MEMORY_SOURCE_FILES,
+      diagnosticHandler: collector);
+
+  collector.checkMessages([
+      const Expected.error(MessageKind.MAIN_HAS_PART_OF)]);
+}
+
+testImportPart() async {
+  var collector = new DiagnosticCollector();
+  await runCompiler(
+      entryPoint: Uri.parse('memory:lib.dart'),
+      memorySourceFiles: MEMORY_SOURCE_FILES,
+      diagnosticHandler: collector);
+
+  collector.checkMessages([
+      const Expected.error(MessageKind.IMPORT_PART_OF),
+      const Expected.info(MessageKind.IMPORT_PART_OF_HERE)]);
+}
+
 testMissingImports() async {
   var collector = new DiagnosticCollector();
   await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       diagnosticHandler: collector);
-  Expect.equals(4, collector.errors.length);
-  Expect.equals(1, collector.warnings.length);
+
+  collector.checkMessages([
+      const Expected.error(MessageKind.READ_SCRIPT_ERROR),
+      const Expected.error(MessageKind.LIBRARY_NOT_FOUND),
+      const Expected.error(MessageKind.READ_SCRIPT_ERROR),
+      const Expected.error(MessageKind.READ_SCRIPT_ERROR),
+      const Expected.warning(MessageKind.NOT_ASSIGNABLE)]);
 }
 
 testMissingMain() async {
@@ -42,12 +84,14 @@
   await runCompiler(
       entryPoint: Uri.parse('memory:missing.dart'),
       diagnosticHandler: collector);
-  Expect.equals(1, collector.errors.length);
-  Expect.equals(0, collector.warnings.length);
+  collector.checkMessages([
+      const Expected.error(MessageKind.READ_SELF_ERROR)]);
 }
 
 void main() {
   asyncTest(() async {
+    await testEntryPointIsPart();
+    await testImportPart();
     await testMissingImports();
     await testMissingMain();
   });
diff --git a/tests/compiler/dart2js/inference_stats_test.dart b/tests/compiler/dart2js/inference_stats_test.dart
index e742b0a..a85ca39 100644
--- a/tests/compiler/dart2js/inference_stats_test.dart
+++ b/tests/compiler/dart2js/inference_stats_test.dart
@@ -9,8 +9,9 @@
 import 'dart:async';
 import 'package:test/test.dart';
 import 'package:dart2js_info/info.dart';
+import 'package:dart2js_info/src/util.dart' show
+    recursiveDiagnosticString;
 import 'memory_compiler.dart';
-import 'dart:io';
 
 main() {
   test('nothing is reachable, nothing to count', () {
diff --git a/tests/compiler/dart2js/js_backend_cps_ir.dart b/tests/compiler/dart2js/js_backend_cps_ir.dart
deleted file mode 100644
index b5f395a..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir.dart
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Test that the CPS IR code generator compiles programs and produces the
-// the expected output.
-
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/apiimpl.dart' show
-    CompilerImpl;
-import 'memory_compiler.dart';
-import 'package:compiler/src/js/js.dart' as js;
-import 'package:compiler/src/elements/elements.dart' show
-    ClassElement,
-    Element;
-
-const String TEST_MAIN_FILE = 'test.dart';
-
-class TestEntry {
-  final String source;
-  final String expectation;
-  final String elementName;
-
-  const TestEntry(this.source, [this.expectation])
-    : elementName = null;
-
-  const TestEntry.forMethod(this.elementName,
-      this.source, this.expectation);
-}
-
-String formatTest(Map test) {
-  return test[TEST_MAIN_FILE];
-}
-
-String getCodeForMain(CompilerImpl compiler) {
-  Element mainFunction = compiler.mainFunction;
-  js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
-  return js.prettyPrint(ast, compiler).getText();
-}
-
-String getCodeForMethod(CompilerImpl compiler,
-                        String name) {
-  Element foundElement;
-  for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
-    if (element.toString() == name) {
-      if (foundElement != null) {
-        Expect.fail('Multiple compiled elements are called $name');
-      }
-      foundElement = element;
-    }
-  }
-
-  if (foundElement == null) {
-    Expect.fail('There is no compiled element called $name');
-  }
-
-  js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
-  return js.prettyPrint(ast, compiler).getText();
-}
-
-runTests(List<TestEntry> tests) {
-  for (TestEntry test in tests) {
-    Map files = {TEST_MAIN_FILE: test.source};
-    asyncTest(() async {
-      Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
-      try {
-        CompilationResult result = await runCompiler(
-            entryPoint: uri,
-            memorySourceFiles: files,
-            options: <String>['--use-cps-ir']);
-        Expect.isTrue(result.isSuccess);
-        CompilerImpl compiler = result.compiler;
-        String expectation = test.expectation;
-        if (expectation != null) {
-          String expected = test.expectation;
-          String found = test.elementName == null
-              ? getCodeForMain(compiler)
-              : getCodeForMethod(compiler, test.elementName);
-          if (expected != found) {
-            Expect.fail('Expected:\n$expected\nbut found\n$found');
-          }
-        }
-      } catch (e, st) {
-        print(e);
-        print(st);
-        Expect.fail('The following test failed to compile:\n'
-                    '${formatTest(files)}');
-      }
-    });
-  }
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
deleted file mode 100644
index 614a102..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests for basic functionality.
-
-library basic_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry(r"""
-main() {
-  var e = 1;
-  var l = [1, 2, 3];
-  var m = {'s': 1};
-
-  print('(' ')');
-  print('(${true})');
-  print('(${1})');
-  print('(${[1, 2, 3]})');
-  print('(${{'s': 1}})');
-  print('($e)');
-  print('($l)');
-  print('($m)');
-}""",r"""
-function() {
-  var l = [1, 2, 3], m = P.LinkedHashMap_LinkedHashMap$_literal(["s", 1]), value_ = C.JSArray_methods, res, v0, v1;
-  P.print("()");
-  P.print("(true)");
-  P.print("(1)");
-  if (!(typeof (res = value_.toString$0(v0 = [1, 2, 3])) === "string"))
-    throw H.wrapException(H.argumentErrorValue(v0));
-  P.print("(" + res + ")");
-  if (!(typeof (v1 = P.Maps_mapToString(v0 = P.LinkedHashMap_LinkedHashMap$_literal(["s", 1]))) === "string"))
-    throw H.wrapException(H.argumentErrorValue(v0));
-  P.print("(" + v1 + ")");
-  P.print("(1)");
-  if (!(typeof (res = value_.toString$0(l)) === "string"))
-    throw H.wrapException(H.argumentErrorValue(l));
-  P.print("(" + res + ")");
-  if (!(typeof (v0 = P.Maps_mapToString(m)) === "string"))
-    throw H.wrapException(H.argumentErrorValue(m));
-  P.print("(" + v0 + ")");
-}"""),
-  const TestEntry("""
-foo(a, [b = "b"]) { print(b); return b; }
-bar(a, {b: "b", c: "c"}) { print(c); return c; }
-main() {
-  foo(0);
-  foo(1, 2);
-  bar(3);
-  bar(4, b: 5);
-  bar(6, c: 7);
-  bar(8, b: 9, c: 10);
-}
-""",
-"""
-function() {
-  P.print("b");
-  P.print(2);
-  P.print("c");
-  P.print("c");
-  P.print(7);
-  P.print(10);
-}"""),
-  const TestEntry(
-  """
-foo(a) {
-  print(a);
-  return a;
-}
-main() {
-  var a = 10;
-  var b = 1;
-  var t;
-  t = a;
-  a = b;
-  b = t;
-  print(a);
-  print(b);
-  print(b);
-  print(foo(a));
-}
-  """,
-  """
-function() {
-  P.print(1);
-  P.print(10);
-  P.print(10);
-  P.print(1);
-  P.print(1);
-}"""),
-  const TestEntry(
-  """
-foo() { print(42); return 42; }
-main() { return foo(); }
-  """,
-  """
-function() {
-  var v0 = H.S(42);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-  return 42;
-}"""),
-  const TestEntry("main() {}"),
-  const TestEntry("main() { return 42; }"),
-  const TestEntry("main() { return; }", """
-function() {
-}"""),
-  // Constructor invocation
-  const TestEntry("""
-main() {
-  print(new Set());
-  print(new Set.from([1, 2, 3]));
-}""", r"""
-function() {
-  P.print(P._LinkedHashSet$(null));
-  P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
-}"""),
-  // Call synthetic constructor.
-  const TestEntry("""
-class C {}
-main() {
-  print(new C());
-}"""),
-  // Method invocation
-  const TestEntry("""
-main() {
-  print(new DateTime.now().isBefore(new DateTime.now()));
-}""", r"""
-function() {
-  var v0 = H.S(Date.now() < Date.now());
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  // Static calls
-  const TestEntry("""
-foo() { print(42); }
-main() { foo(); }
-""", r"""
-function() {
-  var v0 = H.S(42);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  // Static getters
-  const TestEntry("""
-var foo = 42;
-main() { print(foo); }
-""", r"""
-function() {
-  var v0 = H.S($.foo);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry("""
-get foo { print(42); }
-main() { foo; }
-""", r"""
-function() {
-  var v0 = H.S(42);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  // Static setters
-  const TestEntry("""
-var foo = 0;
-main() { print(foo = 42); }
-""", r"""
-function() {
-  var v0;
-  $.foo = 42;
-  v0 = H.S(42);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry("""
-set foo(x) { print(x); }
-main() { foo = 42; }
-""", r"""
-function() {
-  var v0 = H.S(42);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  // Assert
-  const TestEntry("""
-foo() { print('X'); }
-main() {
-  assert(true);
-  assert(false);
-  assert(foo());
-  print('Done');
-}""", r"""
-function() {
-  P.print("Done");
-}""")
-];
-
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
deleted file mode 100644
index f3d55a0..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests of closures.
-
-library closures_test;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  x = x + '1';
-  print(a());
-}
-""",
-r"""
-function(x) {
-  P.print(J.$add$ns(x, "1"));
-}"""),
-
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  x = x + '1';
-  print(a());
-  return a;
-}
-""",
-r"""
-function(x) {
-  var _box_0 = {}, a = new V.main_a(_box_0);
-  _box_0.x = x;
-  _box_0.x = J.$add$ns(_box_0.x, "1");
-  P.print(a.call$0());
-  return a;
-}"""),
-
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  print(a());
-}
-""",
-r"""
-function(x) {
-  P.print(x);
-}"""),
-
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  print(a());
-  return a;
-}
-""",
-r"""
-function(x) {
-  var a = new V.main_a(x);
-  P.print(a.call$0());
-  return a;
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () => x;
-  x = x + 1;
-  print(a());
-}
-""",
-r"""
-function() {
-  var v0 = H.S(122 + 1);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () => x;
-  x = x + 1;
-  print(a());
-  return a;
-}
-""",
-r"""
-function() {
-  var _box_0 = {}, a = new V.main_closure(_box_0), v0;
-  _box_0.x = 122;
-  _box_0.x = _box_0.x + 1;
-  v0 = H.S(a.call$0());
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-  return a;
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () {
-    var y = x;
-    return () => y;
-  };
-  x = x + 1;
-  print(a()());
-}
-""",
-r"""
-function() {
-  var v0 = H.S(122 + 1);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () {
-    var y = x;
-    return () => y;
-  };
-  x = x + 1;
-  print(a()());
-  return a;
-}
-""",
-r"""
-function() {
-  var _box_0 = {}, a = new V.main_closure(_box_0), v0;
-  _box_0.x = 122;
-  _box_0.x = _box_0.x + 1;
-  v0 = H.S(a.call$0().call$0());
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-  return a;
-}"""),
-
-  const TestEntry("""
-main() {
-  var a;
-  for (var i=0; i<10; i++) {
-    a = () => i;
-  }
-  print(a());
-}
-""",
-r"""
-function() {
-  var a = null, i = 0, v0;
-  for (; i < 10; a = new V.main_closure(i), i = i + 1)
-    ;
-  v0 = H.S(a.call$0());
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-  const TestEntry("""
-class A {
-  a() => 1;
-  b() => () => a();
-}
-main() {
-  print(new A().b()());
-}
-""",
-r"""
-function() {
-  var v0 = H.S(new V.A_b_closure(V.A$()).call$0());
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-  const TestEntry("""
-staticMethod(x) { print(x); return x; }
-main(x) {
-  var tearOff = staticMethod;
-  print(tearOff(123));
-}
-""",
-r"""
-function(x) {
-  P.print(123);
-  P.print(123);
-}"""),
-
-  const TestEntry("""
-class Foo {
-  instanceMethod(x) => x;
-}
-main(x) {
-  var tearOff = new Foo().instanceMethod;
-  print(tearOff(123));
-}
-""",
-r"""
-function(x) {
-  V.Foo$();
-  P.print(123);
-}"""),
-
-  const TestEntry("""
-class Foo {
-  instanceMethod(x) => x;
-}
-main(x) {
-  var tearOff = new Foo().instanceMethod;
-  print(tearOff(123));
-  print(tearOff(321));
-}
-""",
-r"""
-function(x) {
-  V.Foo$();
-  P.print(123);
-  P.print(321);
-}"""),
-
-  const TestEntry("""
-class Foo {
-  get getter {
-    print('getter');
-    return (x) => x;
-  }
-}
-main(x) {
-  var notTearOff = new Foo().getter;
-  print(notTearOff(123));
-  print(notTearOff(321));
-}
-""",
-r"""
-function(x) {
-  var v0 = new V.Foo_getter_closure();
-  V.Foo$();
-  P.print("getter");
-  P.print(v0.call$1(123));
-  P.print(v0.call$1(321));
-}"""),
-
-  const TestEntry("""
-class Foo {
-  get getter {
-    print('getter');
-    return (x) => x;
-  }
-}
-main(x) {
-  var notTearOff = new Foo().getter;
-  print(notTearOff(123));
-}
-""",
-r"""
-function(x) {
-  V.Foo$();
-  P.print("getter");
-  P.print(new V.Foo_getter_closure().call$1(123));
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_codeUnitAt_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_codeUnitAt_test.dart
deleted file mode 100644
index 9da3350..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_codeUnitAt_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// Tests for constant folding and lowering String.codeUnitAt.
-
-library basic_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-
-  // Constant folding.
-  const TestEntry(r"""
-main() {
-  print('A'.codeUnitAt(0));
-}""",r"""
-function() {
-  var v0 = H.S(65);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-
-  // Bounds checking.
-  const TestEntry.forMethod('function(foo)',
-r"""
-foo(s) {
-  var sum = 0;
-  for (int i = 0; i < s.length; i++) sum += s.codeUnitAt(i);
-  return sum;
-}
-main() {
-  print(foo('ABC'));
-  print(foo('Hello'));
-}""",r"""
-function(s) {
-  var v0 = s.length, sum = 0, i = 0;
-  for (; i < v0; sum = sum + s.charCodeAt(i), i = i + 1)
-    ;
-  return sum;
-}"""),
-];
-
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
deleted file mode 100644
index a3d9bcd..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// Tests of interceptors.
-
-library constructor_test;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-class Base {
-  var x;
-  Base(this.x);
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x);
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function() {
-  var v0 = H.S(1);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-  const TestEntry("""
-class Base {
-  var x;
-  Base(this.x);
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x) {
-    print(x);
-  }
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function() {
-  P.print(1);
-  P.print(1);
-}"""),
-
-  const TestEntry("""
-class Base0 {
-  Base0() {
-    print('Base0');
-  }
-}
-class Base extends Base0 {
-  var x;
-  Base(this.x);
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x) {
-    print(x);
-  }
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function() {
-  P.print("Base0");
-  P.print(1);
-  P.print(1);
-}"""),
-
-  const TestEntry("""
-class Base0 {
-  Base0() {
-    print('Base0');
-  }
-}
-class Base extends Base0 {
-  var x;
-  Base(x1) : x = (() => ++x1) {
-    print(x1); // use boxed x1
-  }
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x) {
-    print(x);
-  }
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function() {
-  var _box_0 = {};
-  _box_0.x1 = 1;
-  P.print("Base0");
-  P.print(_box_0.x1);
-  P.print(1);
-  P.print(new V.Base_closure(_box_0));
-}"""),
-
-  const TestEntry("""
-foo(x) {
-  print(x);
-}
-class Base {
-  var x1 = foo('x1');
-  var x2;
-  var x3 = foo('x3');
-  Base() : x2 = foo('x2');
-}
-class Sub extends Base {
-  var y1 = foo('y1');
-  var y2;
-  var y3;
-  Sub() : y2 = foo('y2'), super(), y3 = foo('y3');
-}
-main() {
-  new Sub();
-}
-""",
-r"""
-function() {
-  V.foo("y1");
-  V.foo("y2");
-  V.foo("x1");
-  V.foo("x3");
-  V.foo("x2");
-  V.foo("y3");
-}"""),
-
-
-  const TestEntry("""
-class Bar {
-  Bar(x, {y, z: 'z', w: '_', q}) {
-    print(x);
-    print(y);
-    print(z);
-    print(w);
-    print(q);
-  }
-}
-class Foo extends Bar {
-  Foo() : super('x', y: 'y', w: 'w');
-}
-main() {
-  new Foo();
-}
-""",
-r"""
-function() {
-  P.print("x");
-  P.print("y");
-  P.print("z");
-  P.print("w");
-  P.print(null);
-}"""),
-  const TestEntry(r"""
-class C<T> {
-  foo() => T;
-}
-main() {
-  print(new C<int>().foo());
-}""", r"""
-function() {
-  var v0 = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.C$(P.$int), 0))));
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry(r"""
-class C<T> {
-  foo() => C;
-}
-main() {
-  print(new C<int>().foo());
-}""", r"""
-function() {
-  var v0;
-  V.C$();
-  v0 = H.S(C.Type_C_cdS);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry.forMethod('generative_constructor(C#)', r"""
-class C<T> {
-  C() { print(T); }
-  foo() => print(T);
-}
-main() {
-  new C<int>();
-}""", r"""
-function($T) {
-  var v0 = H.setRuntimeTypeInfo(new V.C(), [$T]);
-  v0.C$0();
-  return v0;
-}"""),
-  const TestEntry.forMethod('generative_constructor(C#)', r"""
-class C<T> {
-  var x;
-  C() : x = new D<T>();
-}
-class D<T> {
-  foo() => T;
-}
-main() {
-  print(new C<int>().x.foo());
-}""", r"""
-function($T) {
-  return H.setRuntimeTypeInfo(new V.C(V.D$($T)), [$T]);
-}"""),
-
-
-  const TestEntry(r"""
-class A {
-  var x;
-  A() : this.b(1);
-  A.b(this.x);
-}
-main() {
-  print(new A().x);
-}""", r"""
-function() {
-  var v0 = H.S(1);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-
-const TestEntry(r"""
-class Foo {
-  factory Foo.make(x) {
-    print('Foo');
-    return new Foo.create(x);
-  }
-  var x;
-  Foo.create(this.x);
-}
-main() {
-  print(new Foo.make(5));
-}""", r"""
-function() {
-  P.print("Foo");
-  P.print(new V.Foo(5));
-}"""),
-const TestEntry(r"""
-class Foo {
-  factory Foo.make(x) = Foo.create;
-  var x;
-  Foo.create(this.x);
-}
-main() {
-  print(new Foo.make(5));
-}""", r"""
-function() {
-  var v0 = new V.Foo(5), v1 = "Instance of '" + H.Primitives_objectTypeName(v0) + "'";
-  if (!(typeof v1 === "string"))
-    throw H.wrapException(H.argumentErrorValue(v0));
-  v0 = v1;
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-const TestEntry(r"""
-class A {
-  factory A(x) = B<int>;
-  get typevar;
-}
-class B<T> implements A {
-  var x;
-  B(this.x);
-
-  get typevar => T;
-}
-main() {
-  new A(5).typevar;
-}""", r"""
-function() {
-  V.B$(5, P.$int);
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
deleted file mode 100644
index 62f2537..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests of control flow statements.
-
-library control_flow_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() {
-  while (true);
-}
-""", """
-function() {
-  while (true)
-    ;
-}"""),
-  const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
-  while (true) {
-    l: while (true) {
-      while (foo(true)) {
-        if (foo(false)) break l;
-      }
-      print(1);
-    }
-    print(2);
-  }
-}
-""", """
-function() {
-  L1:
-    while (true)
-      L0:
-        while (true)
-          while (true) {
-            P.print(true);
-            if (false) {
-              P.print(1);
-              continue L0;
-            }
-            P.print(false);
-            if (false) {
-              P.print(2);
-              continue L1;
-            }
-          }
-}"""),
-  const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
-  for (int i = 0; foo(true); i = foo(i)) {
-    print(1);
-    if (foo(false)) break;
-  }
-  print(2);
-}""", """
-function() {
-  while (true) {
-    P.print(true);
-    if (true === true) {
-      P.print(1);
-      P.print(false);
-      if (false !== true) {
-        P.print(0);
-        continue;
-      }
-    }
-    P.print(2);
-    return null;
-  }
-}"""),
-const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
- foo(false);
- if (foo(true)) {
-   print(1);
- } else {
-   print(2);
- }
- print(3);
-}""", """
-function() {
-  P.print(false);
-  P.print(true);
-  true ? P.print(1) : P.print(2);
-  P.print(3);
-}"""),
-const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
- foo(false);
- if (foo(true)) {
-   print(1);
-   print(1);
- } else {
-   print(2);
-   print(2);
- }
- print(3);
-}""", """
-function() {
-  P.print(false);
-  P.print(true);
-  if (true) {
-    P.print(1);
-    P.print(1);
-  } else {
-    P.print(2);
-    P.print(2);
-  }
-  P.print(3);
-}"""),
-const TestEntry("""
-main() {
-  if (1) {
-    print('bad');
-  } else {
-    print('good');
-  }
-}""","""
-function() {
-  P.print("good");
-}"""),
-  const TestEntry("""
-foo() { print('2'); return 2; }
-main() {
-  if (foo()) {
-    print('bad');
-  } else {
-    print('good');
-  }
-}""","""
-function() {
-  P.print("2");
-  P.print("good");
-}"""),
-  const TestEntry("""
-main() {
-  var list = [1,2,3,4,5,6];
-  for (var x in list) {
-    print(x);
-  }
-}""",r"""
-function() {
-  var list = [1, 2, 3, 4, 5, 6], i = 0, v0;
-  for (; i < 6; i = i + 1) {
-    v0 = H.S(list[i]);
-    if (typeof dartPrint == "function")
-      dartPrint(v0);
-    else if (typeof console == "object" && typeof console.log != "undefined")
-      console.log(v0);
-    else if (!(typeof window == "object")) {
-      if (!(typeof print == "function"))
-        throw "Unable to print message: " + String(v0);
-      print(v0);
-    }
-  }
-}"""),
-  const TestEntry("""
-main() {
-  var xs = ['x', 'y', 'z'], ys = ['A', 'B', 'C'];
-  var xit = xs.iterator, yit = ys.iterator;
-  while (xit.moveNext() && yit.moveNext()) {
-    print(xit.current);
-    print(yit.current);
-  }
-}""",r"""
-function() {
-  var xs = ["x", "y", "z"], ys = ["A", "B", "C"], i = 0, i1 = 0, current, current1;
-  for (; i < 3; i = i + 1, i1 = i1 + 1) {
-    current = xs[i];
-    if (!(i1 < 3))
-      break;
-    current1 = ys[i1];
-    P.print(current);
-    P.print(current1);
-  }
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart
deleted file mode 100644
index 604c19a..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// Test that the GVN optimization pass works as expected.
-
-library basic_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry(r"""
-foo(x, list) {
-  var sum = 0;
-  for (int k = 0; k < 10; k++) {
-    // Everything can be hoisted out up to the index access which is
-    // blocked by the bounds check.
-    var a = x.left.left;
-    var b = x.left.right;
-    var c = x.right.left;
-    var d = x.right.right;
-    var i = a.value + c.value;
-    var j = b.value + d.value;
-    var z = list[i * j] + i;
-    sum += z;
-  }
-  return sum;
-}
-// Use a different class for each level in the tree, so type inference
-// is not confused.
-class Root {
-  Branch left, right;
-  Root(this.left, this.right);
-}
-class Branch {
-  Leaf left, right;
-  Branch(this.left, this.right);
-}
-class Leaf {
-  int value;
-  Leaf(this.value);
-}
-main() {
-  var x1 = new Leaf(1);
-  var x2 = new Leaf(10);
-  var x3 = new Leaf(20);
-  var x4 = new Leaf(-10);
-  var y1 = new Branch(x1, x2);
-  var y2 = new Branch(x3, x4);
-  var z  = new Root(y1, y2);
-  print(foo(z, [1,2,3,4,5,6,7,8,9,10]));
-}
-""",r"""
-function() {
-  var v0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], sum = 0, k = 0, i, v1;
-  for (; k < 10; sum = sum + (i + v0[v1]), k = k + 1) {
-    i = 1 + 20;
-    v1 = i * (10 + -10);
-    if (v1 < 0 || v1 >= 10)
-      return H.ioore(v0, v1);
-  }
-  v0 = H.S(sum);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
deleted file mode 100644
index 382736c..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests of interceptors.
-
-library interceptors_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() {
-  var g = 1;
-
-  var x = g + 3;
-  print(x);
-}""",
-r"""
-function() {
-  var v0 = H.S(4);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry("""
-main() {
-  var l = ['hest', ['h', 'e', 's', 't']];
-  print(l.length);
-  for (int i  = 0; i < l.length; i++) {
-    var x = l[i];
-    for (int j = 0; j < x.length; j++) {
-      print(x[j]);
-    }
-  }
-}""",
-r"""
-function() {
-  var l = ["hest", ["h", "e", "s", "t"]], i = 0, x, j;
-  for (P.print(2); i < 2; i = i + 1) {
-    x = l[i];
-    for (j = 0; j < x.length; j = j + 1)
-      P.print(x[j]);
-  }
-}"""),
-];
-
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
deleted file mode 100644
index ad9d2e7..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests of literals.
-
-library literals_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() {
-  print([]);
-  print([1]);
-  print([1, 2]);
-  print([1, [1, 2]]);
-  print({});
-  print({1: 2});
-  print({[1, 2]: [3, 4]});
-}
-""",
-r"""
-function() {
-  P.print([]);
-  P.print([1]);
-  P.print([1, 2]);
-  P.print([1, [1, 2]]);
-  P.print(P.LinkedHashMap_LinkedHashMap$_empty());
-  P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
-  P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators2_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators2_test.dart
deleted file mode 100644
index 21ffdc5..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_operators2_test.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// Tests of operators.
-
-library operators_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-
-  const TestEntry(r"""
-foo(a, b) => ((a & 0xff0000) >> 1) & b;
-main() {
-  print(foo(123, 234));
-  print(foo(0, 2));
-}""", r"""
-function() {
-  P.print((123 & 16711680) >>> 1 & 234);
-  P.print((0 & 16711680) >>> 1 & 2);
-}"""),
-
-  const TestEntry(r"""
-foo(a) => ~a;
-main() {
-  print(foo(1));
-  print(foo(10));
-}""", r"""
-function() {
-  P.print(~1 >>> 0);
-  P.print(~10 >>> 0);
-}"""),
-
-  const TestEntry.forMethod('function(foo)',
-      r"""
-foo(a) => a % 13;
-main() {
-  print(foo(5));
-  print(foo(-100));
-}""", r"""
-function(a) {
-  var result = a % 13;
-  return result === 0 ? 0 : result > 0 ? result : 13 < 0 ? result - 13 : result + 13;
-}"""),
-
-  const TestEntry(r"""
-foo(a) => a % 13;
-main() {
-  print(foo(5));
-  print(foo(100));
-}""", r"""
-function() {
-  P.print(5 % 13);
-  P.print(100 % 13);
-}"""),
-
-  const TestEntry(r"""
-foo(a) => a.remainder(13);
-main() {
-  print(foo(5));
-  print(foo(-100));
-}""", r"""
-function() {
-  P.print(5 % 13);
-  P.print(-100 % 13);
-}"""),
-
-  const TestEntry.forMethod('function(foo)',
-      r"""
-foo(a) => a ~/ 13;
-main() {
-  print(foo(5));
-  print(foo(-100));
-}""", r"""
-function(a) {
-  var v0;
-  return (a | 0) === a && (13 | 0) === 13 ? a / 13 | 0 : J.getInterceptor$n(v0 = a / 13).toInt$0(v0);
-}"""),
-
-  const TestEntry(r"""
-foo(a) => a ~/ 13;
-main() {
-  print(foo(5));
-  print(foo(100));
-}""", r"""
-function() {
-  P.print(5 / 13 | 0);
-  P.print(100 / 13 | 0);
-}"""),
-
-  const TestEntry.forMethod('function(foo)',
-      r"""
-foo(a) => a ~/ 13;
-main() {
-  print(foo(5));
-  print(foo(8000000000));
-}""", r"""
-function(a) {
-  var v0;
-  return (a | 0) === a && (13 | 0) === 13 ? a / 13 | 0 : J.getInterceptor$n(v0 = a / 13).toInt$0(v0);
-}"""),
-
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
deleted file mode 100644
index 152a552..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests of operators.
-
-library operators_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("main() { return true ? 42 : 'foo'; }"),
-  const TestEntry("""
-var x = 1;
-foo() => ++x > 10;
-main() {
-  print(foo() ? "hello world" : "bad bad");
-}""",r"""
-function() {
-  var v0 = $.x + 1;
-  $.x = v0;
-  v0 = v0 > 10 ? "hello world" : "bad bad";
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry("""
-var x = 1;
-get foo => ++x > 10;
-main() {
-  print(foo ? "hello world" : "bad bad");
-}""",r"""
-function() {
-  var v0 = $.x + 1;
-  $.x = v0;
-  v0 = v0 > 10 ? "hello world" : "bad bad";
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry("""
-var x = 1;
-get foo => ++x > 10;
-main() { print(foo && foo); }
-""", r"""
-function() {
-  var v0 = $.x + 1;
-  $.x = v0;
-  if (v0 > 10) {
-    $.x = v0 = $.x + 1;
-    v0 = v0 > 10;
-  } else
-    v0 = false;
-  v0 = H.S(v0);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry("""
-var x = 1;
-get foo => ++x > 10;
-main() { print(foo || foo); }
-""",r"""
-function() {
-  var v0 = $.x + 1;
-  $.x = v0;
-  if (v0 > 10)
-    v0 = true;
-  else {
-    $.x = v0 = $.x + 1;
-    v0 = v0 > 10;
-  }
-  v0 = H.S(v0);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-const TestEntry("""
-get foo => foo;
-main() { print(foo || foo); }
-""","""
-function() {
-  V.foo();
-}"""),
-
-// Needs interceptor calling convention
-//const TestEntry("""
-//class Foo {
-//  operator[]=(index, value) {
-//    print(value);
-//  }
-//}
-//main() {
-//  var foo = new Foo();
-//  foo[5] = 6;
-//}""", r"""
-//function() {
-//  V.Foo$().$indexSet(5, 6);
-//}
-//"""),
-
-const TestEntry("""
-main() {
-  var list = [1, 2, 3];
-  list[1] = 6;
-  print(list);
-}""", r"""
-function() {
-  var list = [1, 2, 3], res, v0;
-  list[1] = 6;
-  if (!(typeof (res = C.JSArray_methods.toString$0(list)) === "string"))
-    throw H.wrapException(H.argumentErrorValue(list));
-  v0 = res;
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
deleted file mode 100644
index fcdc6cb..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests for the runtime type implementation.
-
-library basic_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const String getTypeArgument = r'H.getTypeArgumentByIndex';
-const String getSubstitutedTypeArgument = 'H.getRuntimeTypeArgument';
-const String typeToString = r'H.runtimeTypeToString';
-const String createType = r'H.createRuntimeType';
-
-const List<TestEntry> tests = const [
-    const TestEntry(r"""
-class C<T> {
-  foo() => print(T);
-}
-
-main() {
-  new C<int>().foo();
-}""",
-r"""
-function() {
-  var v0 = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.C$(P.$int), 0))));
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-    const TestEntry(r"""
-class C<T, U> {
-  foo() => print(U);
-}
-
-class D extends C<int, double> {}
-
-main() {
-  new D().foo();
-}""",
-r"""
-function() {
-  var v0 = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getRuntimeTypeArgument(V.D$(), "C", 1))));
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-  const TestEntry(r"""
-class C<T> {
-  foo() => new D<C<T>>();
-}
-class D<T> {
-  bar() => T;
-}
-main() {
-  print(new C<int>().foo().bar());
-}""", r"""
-function() {
-  var v0 = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.D$([V.C, H.getTypeArgumentByIndex(V.C$(P.$int), 0)]), 0))));
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-    const TestEntry.forMethod('generative_constructor(C#)', r"""
-class C<X, Y, Z> {
-  foo() => 'C<$X $Y, $Z>';
-}
-main() {
-  new C<C, int, String>().foo();
-}""", r"""
-function($X, $Y, $Z) {
-  return H.setRuntimeTypeInfo(new V.C(), [$X, $Y, $Z]);
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
index db46dcbf..2c68f48 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
@@ -14,6 +14,7 @@
 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
 import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart' as ir;
 import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/elements/elements.dart';
 
 const String TEST_MAIN_FILE = 'test.dart';
@@ -78,8 +79,9 @@
       }
 
       Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
-      compiler.backend.functionCompiler.cpsBuilderTask.builderCallback =
-          cacheIrNodeForMain;
+      JavaScriptBackend backend = compiler.backend;
+      var functionCompiler = backend.functionCompiler;
+      functionCompiler.cpsBuilderTask.builderCallback = cacheIrNodeForMain;
 
       return compiler.run(uri).then((bool success) {
         Expect.isTrue(success);
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_supercall_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_supercall_test.dart
deleted file mode 100644
index bb19616..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_supercall_test.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2014, 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.
-
-// Tests of interceptors.
-
-library supercall_test;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-class Base {
-  m(x) {
-    print(x+1);
-  }
-}
-class Sub extends Base {
-  m(x) => super.m(x+10);
-}
-main() {
-  new Sub().m(100);
-}""",
-r"""
-function() {
-  var v0;
-  V.Sub$();
-  v0 = H.S(100 + 10 + 1);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-  // Reenable when we support compiling functions that
-  // need interceptor calling convention.
-// const TestEntry.forMethod('function(Sub#+)', """
-// class Base {
-//   m(x) {
-//     print(x+1000);
-//   }
-//   operator+(x) => m(x+10);
-// }
-// class Sub extends Base {
-//   m(x) => super.m(x+100);
-//   operator+(x) => super + (x+1);
-// }
-// main() {
-//   new Sub() + 10000;
-// }""",
-// r"""
-// function(x) {
-//   var v0, v1, v2;
-//   v0 = 1;
-//   v1 = J.getInterceptor$ns(x).$add(x, v0);
-//   v2 = this;
-//   return V.Base.prototype.$add.call(null, v2, v1);
-// }"""),
-
-const TestEntry("""
-class Base {
-  var field = 123;
-}
-class Sub extends Base {
-  m(x) => x + super.field;
-}
-main() {
-  print(new Sub().m(10));
-}""",
-r"""
-function() {
-  var v0 = H.S(10 + V.Sub$().field);
-  if (typeof dartPrint == "function")
-    dartPrint(v0);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(v0);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(v0);
-    print(v0);
-  }
-}"""),
-
-
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/least_upper_bound_test.dart b/tests/compiler/dart2js/least_upper_bound_test.dart
index c4706bf..7f15f88 100644
--- a/tests/compiler/dart2js/least_upper_bound_test.dart
+++ b/tests/compiler/dart2js/least_upper_bound_test.dart
@@ -2,7 +2,7 @@
 // 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 subtype_test;
+library least_upper_bound_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/lookup_member_test.dart b/tests/compiler/dart2js/lookup_member_test.dart
index d43bcd0..aec363a 100644
--- a/tests/compiler/dart2js/lookup_member_test.dart
+++ b/tests/compiler/dart2js/lookup_member_test.dart
@@ -2,7 +2,7 @@
 // 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 subtype_test;
+library lookup_member_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/members_test.dart b/tests/compiler/dart2js/members_test.dart
index 59dbf97..0856b32 100644
--- a/tests/compiler/dart2js/members_test.dart
+++ b/tests/compiler/dart2js/members_test.dart
@@ -8,11 +8,18 @@
 import "package:async_helper/async_helper.dart";
 import 'type_test_helper.dart';
 import 'package:compiler/src/dart_types.dart';
-import "package:compiler/src/elements/elements.dart"
-       show Element, ClassElement, MemberSignature, Name, PublicName,
-            DeclaredMember, Member;
-import "package:compiler/src/resolution/class_members.dart"
-  show MembersCreator, DeclaredMember, ErroneousMember, SyntheticMember;
+import "package:compiler/src/elements/elements.dart" show
+    Element,
+    ClassElement,
+    MemberSignature,
+    Name,
+    PublicName,
+    Member;
+import "package:compiler/src/resolution/class_members.dart" show
+    MembersCreator,
+    DeclaredMember,
+    ErroneousMember,
+    SyntheticMember;
 
 void main() {
   testClassMembers();
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index 28d7948..ad46907 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -124,7 +124,8 @@
       Expect.isTrue(messageFound,
           '${template.kind}} does not match any in\n '
           '${messages.join('\n ')}');
-      Expect.isFalse(compiler.reporter.hasCrashed);
+      var reporter = compiler.reporter;
+      Expect.isFalse(reporter.hasCrashed);
       if (!unexpectedMessages.isEmpty) {
         for (CollectedMessage message in unexpectedMessages) {
           print("Unexpected message: $message");
diff --git a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
index 3059fd1..ed8d8fd 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
@@ -27,7 +27,8 @@
     try {
       return f();
     } on SpannableAssertionFailure catch (e) {
-      mirrorSystem.compiler.reportAssertionFailure(e);
+      var reporter = mirrorSystem.compiler.reporter;
+      reporter.reportAssertionFailure(e);
       rethrow;
     }
   }
diff --git a/tests/compiler/dart2js/mirrors_lookup_test.dart b/tests/compiler/dart2js/mirrors_lookup_test.dart
index 2e8802f..32e04e1 100644
--- a/tests/compiler/dart2js/mirrors_lookup_test.dart
+++ b/tests/compiler/dart2js/mirrors_lookup_test.dart
@@ -2,7 +2,7 @@
 // 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 dart2js.test.memory_source_file_helper;
+library dart2js.test.mirrors_lookup;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/parser_test.dart b/tests/compiler/dart2js/parser_test.dart
index 4674201..2ee3d9e 100644
--- a/tests/compiler/dart2js/parser_test.dart
+++ b/tests/compiler/dart2js/parser_test.dart
@@ -155,19 +155,23 @@
 }
 
 void testNullOperators() {
-  Expression node = parseStatement("a ?? b;").expression;
+  ExpressionStatement statement = parseStatement("a ?? b;");
+  Expression node = statement.expression;
   Expect.isNotNull(node.asSend());
   Expect.isTrue(node.asSend().isIfNull);
 
-  node = parseStatement("a ??= b;").expression;
+  statement = parseStatement("a ??= b;");
+  node = statement.expression;
   Expect.isNotNull(node.asSendSet());
   Expect.isTrue(node.asSendSet().isIfNullAssignment);
 
-  node = parseStatement("a?.b;").expression;
+  statement = parseStatement("a?.b;");
+  node = statement.expression;
   Expect.isNotNull(node.asSend());
   Expect.isTrue(node.asSend().isConditional);
 
-  node = parseStatement("a?.m();").expression;
+  statement = parseStatement("a?.m();");
+  node = statement.expression;
   Expect.isNotNull(node.asSend());
   Expect.isTrue(node.asSend().isConditional);
 }
diff --git a/tests/compiler/dart2js/related_types_test.dart b/tests/compiler/dart2js/related_types_test.dart
index dfb50b4..63b424a 100644
--- a/tests/compiler/dart2js/related_types_test.dart
+++ b/tests/compiler/dart2js/related_types_test.dart
@@ -2,7 +2,7 @@
 // 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 related_types;
+library related_types.test;
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index bc5878e..3396e53 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -198,8 +198,10 @@
                            '}');
       ClassElement foo = compiler.mainApp.find('Foo');
       foo.ensureResolved(compiler.resolution);
-      foo.lookupLocalMember('t').computeType(compiler.resolution);
-      foo.lookupLocalMember('foo').computeType(compiler.resolution);
+      MemberElement tMember = foo.lookupLocalMember('t');
+      tMember.computeType(compiler.resolution);
+      MemberElement fooMember = foo.lookupLocalMember('foo');
+      fooMember.computeType(compiler.resolution);
       compiler.resolver.resolve(foo.lookupLocalMember('bar'));
       DiagnosticCollector collector = compiler.diagnosticCollector;
       Expect.equals(0, collector.warnings.length);
diff --git a/tests/compiler/dart2js/source_map_validator_helper.dart b/tests/compiler/dart2js/source_map_validator_helper.dart
index 84e410c..ef0aff1 100644
--- a/tests/compiler/dart2js/source_map_validator_helper.dart
+++ b/tests/compiler/dart2js/source_map_validator_helper.dart
@@ -8,7 +8,7 @@
 
 import 'package:path/path.dart' as path;
 import 'package:expect/expect.dart';
-import 'package:source_maps/source_maps.dart' hide SourceFile;
+import 'package:source_maps/source_maps.dart';
 import 'package:compiler/src/apiimpl.dart';
 import 'package:compiler/src/elements/elements.dart'
     show AstElement,
diff --git a/tests/compiler/dart2js/sourcemaps/colors.dart b/tests/compiler/dart2js/sourcemaps/colors.dart
index 10aa511..b6fa6b4 100644
--- a/tests/compiler/dart2js/sourcemaps/colors.dart
+++ b/tests/compiler/dart2js/sourcemaps/colors.dart
@@ -4,7 +4,7 @@
 
 /// Utility library for creating web colors.
 
-library colors;
+library sourcemaps.colors;
 
 /// A web color.
 abstract class Color {
diff --git a/tests/compiler/dart2js/subtypeset_test.dart b/tests/compiler/dart2js/subtypeset_test.dart
index 6673041..1853a8b 100644
--- a/tests/compiler/dart2js/subtypeset_test.dart
+++ b/tests/compiler/dart2js/subtypeset_test.dart
@@ -4,7 +4,7 @@
 
 // Test for iterators on for [SubclassNode].
 
-library world_test;
+library subtypeset_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/type_order_test.dart b/tests/compiler/dart2js/type_order_test.dart
index dff24fc..87c2aa2 100644
--- a/tests/compiler/dart2js/type_order_test.dart
+++ b/tests/compiler/dart2js/type_order_test.dart
@@ -2,7 +2,7 @@
 // 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 subtype_test;
+library type_order_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 83f4806..0a2d4e0 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -2,7 +2,7 @@
 // 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 subtype_test;
+library type_representation_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index df06008..fc04a58 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -14,6 +14,7 @@
     show Compiler;
 import 'package:compiler/src/elements/elements.dart'
     show Element,
+         MemberElement,
          TypeDeclarationElement,
          ClassElement;
 
@@ -96,7 +97,8 @@
   }
 
   DartType getElementType(String name) {
-    return getElement(name).computeType(compiler.resolution);
+    var element = getElement(name);
+    return element.computeType(compiler.resolution);
   }
 
   DartType operator[] (String name) {
@@ -106,7 +108,7 @@
   }
 
   DartType getMemberType(ClassElement element, String name) {
-    Element member = element.localLookup(name);
+    MemberElement member = element.localLookup(name);
     return member.computeType(compiler.resolution);
   }
 
diff --git a/tests/compiler/dart2js/type_variable_occurrence_test.dart b/tests/compiler/dart2js/type_variable_occurrence_test.dart
index a198cd4..a30a552 100644
--- a/tests/compiler/dart2js/type_variable_occurrence_test.dart
+++ b/tests/compiler/dart2js/type_variable_occurrence_test.dart
@@ -2,7 +2,7 @@
 // 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 subtype_test;
+library type_variable_occurrence_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 4045cfa..3d00167 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -60,9 +60,6 @@
 deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
 deferred_fail_and_retry_worker_test: SkipByDesign # Uses eval to simulate failed loading.
 
-[ $host_checked && $compiler == dart2js && $cps_ir ]
-21724_test: Crash # Please triage this failure.
-
 [ $compiler == none && $runtime == vm ]
 invalid_annotation_test/01: MissingCompileTimeError, OK # vm is lazy
 lookup_map/dead_entry_through_mirrors_test: SkipByDesign # Test for tree-shaking, vm never tree-shakes
@@ -72,14 +69,5 @@
 
 [ $compiler == dart2js && $cps_ir ]
 16407_test: Pass # Please triage this failure.
-code_motion_exception_test: Fail # .toString to null check a primitive, triggered by inlining
 async_stacktrace_test/asyncStar: Crash # (foo()async*{try {tr...  cannot handle sync*/async* functions
-deferred/deferred_class_test: RuntimeError # Z.loadLibrary is not a function
-deferred/deferred_constant2_test: RuntimeError # U.loadLibrary is not a function
-deferred/deferred_constant3_test: RuntimeError # Y.loadLibrary is not a function
-deferred/deferred_constant4_test: RuntimeError # B.loadLibrary is not a function
-deferred/deferred_function_test: Crash # (lib.foo('a')): deferred access is not implemented
-deferred/deferred_mirrors1_test: RuntimeError # U.loadLibrary is not a function
-deferred/deferred_overlapping_test: RuntimeError # E.loadLibrary is not a function
-deferred_split_test: RuntimeError # Z.loadLibrary is not a function
 switch_test/none: Crash # (switch (val){foo:ba...  continue to a labeled switch case
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index ad3536a..dfe56d3 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -21,7 +21,6 @@
 compute_this_script_test: Skip # Issue 17458
 
 [ $compiler == dart2js && $cps_ir ]
-foreign_test: RuntimeError # Fails due to inlining, please triage.  Expect.equals(expected: <1234567891011>, actual: <1234567891011>) fails
 native_exception_test: RuntimeError # Issue 24421
 optimization_hints_test: RuntimeError # Please triage this failure.
 subclassing_constructor_2_test: RuntimeError # Please triage this failure.
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
deleted file mode 100644
index 0a1e13e..0000000
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart
+++ /dev/null
@@ -1,28 +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.
-
-library dromaeo;
-
-import 'dart:async';
-import "dart:convert";
-import 'dart:html';
-import 'dart:math' as Math;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import '../../../samples/third_party/dromaeo/common/common.dart';
-
-part '../../../samples/third_party/dromaeo/tests/Common.dart';
-part '../../../samples/third_party/dromaeo/tests/RunnerSuite.dart';
-
-/**
- * The smoketest equivalent of an individual test run, much like
- * dom-attr-html.dart, dom-modify-html.dart, dom-query-html.dart and others.
- */
-void main() {
-  new Suite(window, 'dom-nothing')
-    .prep(() {})
-    .test('no-op', () {})
-    .end();
-}
-
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart.js b/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
deleted file mode 100644
index d1f3214..0000000
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
+++ /dev/null
@@ -1,9 +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.
-
-window.onload = function(){
-  startTest("dom-nothing");
-  test( "no-op", function(){});
-  endTest();
-};
diff --git a/tests/html/dromaeo_smoke-html.html b/tests/html/dromaeo_smoke-html.html
deleted file mode 100644
index 1cbeca4..0000000
--- a/tests/html/dromaeo_smoke-html.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<!-- The inner smoketest iframe, corresponds to dom-attr-html.html,
-dom-modify-html.html and others in the dromaeo tests directory. -->
-<html>
-<head>
-<script type="application/dart" src="dromaeo_noop/dromaeo_smoke.dart"></script>
-<script src='/root_dart/pkg/browser/lib/dart.js'></script>
-<script src='/root_dart/samples/third_party/dromaeo/htmlrunner.js'></script>
-</head>
-<body>
-</body>
-</html>
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
deleted file mode 100644
index 2f71f9b6..0000000
--- a/tests/html/dromaeo_smoke_test.dart
+++ /dev/null
@@ -1,56 +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.
-
-library dromaeo;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import '../../samples/third_party/dromaeo/web/Dromaeo.dart' as originalTest;
-import 'dart:html';
-import 'dart:async';
-
-/** A variant of the Dromaeo test shoehorned into a unit test. */
-void main() {
-  var combo = '?dartANDhtmlANDnothing';
-  if (!window.location.search.toString().contains(combo)) {
-    if (window.location.href.toString().indexOf("?") == -1) {
-      window.location.href = '${window.location.href}${combo}';
-    } else {
-      window.location.href = '${window.location.href.toString().substring(0,
-          window.location.href.toString().indexOf("?"))}${combo}';
-    }
-  }
-
-  useHtmlConfiguration();
-
-  var scriptSrc = new ScriptElement();
-  scriptSrc.src = '/root_dart/pkg/browser/lib/dart.js';
-  document.head.children.add(scriptSrc);
-  document.body.innerHtml = '''${document.body.innerHtml}
-  <div id="main">
-    <h1 id="overview" class="test"><span>Performance Tests</span>
-    <input type="button" id="pause" class="pause" value="Loading..."/>
-    <div class="bar">
-      <div id="timebar" style="width:25%;">
-        <span class="left">Est.&nbsp;Time:&nbsp;<strong id="left">0:00</strong>
-        </span>
-      </div>
-    </div>
-    <ul id="tests">
-      <li><a href="?dom">Smoke Tests</a></li>
-    </ul>
-  </div>''';
-
-  bool isDone = false;
-  originalTest.main();
-
-  test('dromaeo runs', () {
-    new Timer.periodic(new Duration(milliseconds: 500),
-                       expectAsyncUntil((timer) {
-      if (document.query('.alldone') != null) {
-        timer.cancel();
-        isDone = true;
-      }
-    }, () => isDone));
-  });
-}
diff --git a/tests/html/html.status b/tests/html/html.status
index 1783cf0..cf4c69a 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 interactive_test: Skip # Must be run manually.
-dromaeo_smoke_test: Skip # Issue 14521, 8257
 cross_frame_test: Skip # Test reloads itself. Issue 18558
 
 [ $compiler == none && ($runtime == dartium || $runtime == drt) ]
@@ -58,9 +57,7 @@
 # postMessage in dartium always transfers the typed array buffer, never a view
 postmessage_structured_test/typed_arrays: Fail
 # Dartium seems to lose the data from the dispatchEvent.
-async_test: Fail # Uses spawn, not implemented from a DOM isolate in Dartium
 keyboard_event_test: Fail # Issue 13902
-isolates_test: Fail # Issue 13921
 fileapi_test/getFile: Pass, Fail # Issue 20488
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium ) && $mode == debug ]
@@ -108,8 +105,6 @@
 element_animate_test/simple_timing: RuntimeError # Please triage this failure
 element_types_test/supported_object: RuntimeError # Issue 25155
 element_types_test/supported_embed: RuntimeError # Issue 25155
-event_test: Pass, RuntimeError # Issue 25158 Passes on 46, fails on 47
-history_test/history: Pass, RuntimeError # Issue 25158, passes on 46 fails on 47
 
 [ $runtime == chrome && $system == macos ]
 canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
@@ -351,7 +346,6 @@
 xhr_test/xhr: Pass, Fail # Issue 11602
 dart_object_local_storage_test: Skip  # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
 webgl_1_test: Pass, Fail   # Issue 8219
-canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Pass, Fail # Firefox pre-38 does not like dataUrl videos for drawImage Issue 23479
 text_event_test: Fail # Issue 17893
 
 # Firefox Feature support statuses-
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 71e28ae..5bfd88e 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -56,6 +56,9 @@
 browser/issue_12474_test: CompileTimeError # Issue 22529
 enum_const_test/02: RuntimeError # Issue 21817
 
+[ $compiler == dart2js && $cps_ir ]
+isolate_current_test: RuntimeError # Please triage this failure.
+
 [ $compiler == dart2js && $runtime != d8 ]
 error_exit_at_spawn_test: Skip # Issue 23876
 error_at_spawn_test: Skip # Issue 23876
@@ -84,9 +87,6 @@
 [ $jscl ]
 spawn_uri_multi_test/none: RuntimeError # Issue 13544
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
-pause_test: Fail         # Not implemented yet
-
 [ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
 nested_spawn2_test: Skip # Issue 19127: This test is timing out.
 
@@ -97,31 +97,15 @@
 isolate/spawn_uri_multi_test/01: Skip # Times out. Issue 24795
 
 [ ($compiler == none || $compiler == precompiler) && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
-typed_message_test: Crash, Fail # Issue 13921, 14400
-message_enum_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-compile_time_error_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-isolate_import_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-issue_21398_parent_isolate_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-issue_21398_parent_isolate1_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
+typed_message_test: Skip # Issue 13921, 14400
 isolate_stress_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
-message3_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-start_paused_test: Fail, OK   # Issue 13921 Dom isolates don't support spawnFunction
-object_leak_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
+object_leak_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
 simple_message_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-spawn_uri_missing_from_isolate_test: RuntimeError # Issue 17649
+spawn_uri_missing_from_isolate_test: Skip # Issue 17649
 spawn_uri_missing_test: SkipSlow # Times out.
-isolate_current_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-function_send_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-ondone_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-kill_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-kill2_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
 kill3_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-kill_self_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-handle_error_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-handle_error2_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-handle_error3_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
 timer_isolate_test: Fail, Pass # Issue 15487. Issue 13921: Dom isolates don't support spawnFunction
-deferred_in_isolate2_test: Fail, OK  # Issue 16209, 13921 Dom isolates don't support spawnFunction
+deferred_in_isolate2_test: Skip  # Issue 16209, 13921 Dom isolates don't support spawnFunction
 bool_from_environment_default_value_test: Skip
 int_from_environment_default_value_test: Skip
 string_from_environment_default_value_test: Skip
@@ -139,10 +123,10 @@
 
 [ $compiler != none || $runtime != vm ]
 package_root_test: SkipByDesign  # Uses Isolate.packageRoot
-package_map_test: SkipByDesign  # Uses Isolate.packageMap
-
-[ $compiler == dart2js && $cps_ir ]
-deferred_in_isolate2_test: RuntimeError # A.loadLibrary is not a function
+package_config_test: SkipByDesign  # Uses Isolate.packageConfig
+package_resolve_test: SkipByDesign  # Uses Isolate.resolvePackageUri
+spawn_uri_fail_test: SkipByDesign  # Uses dart:io.
+scenarios/*: SkipByDesign  # Use automatic package resolution and .dart URIs.
 
 [ ($noopt || $compiler == precompiler) ]
 # Imports dart:mirrors
diff --git a/tests/isolate/package_config_test.dart b/tests/isolate/package_config_test.dart
new file mode 100644
index 0000000..1b55194
--- /dev/null
+++ b/tests/isolate/package_config_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2015, 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.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final SPAWN_PACKAGE_CONFIG = "foobar:///no/such/file/";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageConfig(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageConfig: Uri.parse(SPAWN_PACKAGE_CONFIG));
+  p.handler = (msg) {
+    p.close();
+    if (msg[0] != SPAWN_PACKAGE_CONFIG) {
+      throw "Bad package config in child isolate: ${msg[0]}";
+    }
+    if (msg[1] != null) {
+      throw "Non-null loaded package config in isolate: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package config: ${await Isolate.packageConfig}");
+}
+
+testPackageConfig(port) async {
+  var packageConfigStr = Platform.packageConfig;
+  var packageConfig = await Isolate.packageConfig;
+  print("Spawned isolate's package config flag: $packageConfigStr");
+  print("Spawned isolate's loaded package config: $packageConfig");
+  port.send([packageConfigStr, packageConfig?.toString()]);
+}
diff --git a/tests/isolate/package_resolve_test.dart b/tests/isolate/package_resolve_test.dart
new file mode 100644
index 0000000..4a1b584
--- /dev/null
+++ b/tests/isolate/package_resolve_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2015, 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.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final SPAWN_PACKAGE_ROOT = "file:///no/such/package/root/";
+final PACKAGE_URI = "package:foo/bar.dart";
+final PACKAGE_PATH = "file:///no/such/package/root/foo/bar.dart";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    if (msg[0] != SPAWN_PACKAGE_ROOT) {
+      throw "Bad package root in child isolate: ${msg[0]}";
+    }
+    if (msg[1] != PACKAGE_PATH) {
+      throw "Package path not matching: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageRoot = await Isolate.packageRoot;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's loaded package root: $packageRoot");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageRoot?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/package_root_test.dart b/tests/isolate/package_root_test.dart
new file mode 100644
index 0000000..79b1c35
--- /dev/null
+++ b/tests/isolate/package_root_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, 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.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final SPAWN_PACKAGE_ROOT = "file:///no/such/file/";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageRoot(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
+  p.handler = (msg) {
+    p.close();
+    if (msg != SPAWN_PACKAGE_ROOT) {
+      throw "Bad package root in child isolate: $msg";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageRoot(port) async {
+  var packageRoot = await Isolate.packageRoot;
+  print("Spawned isolate's package root: $packageRoot");
+  port.send(packageRoot.toString());
+}
diff --git a/tests/isolate/scenarios/automatic_resolution_root/package_resolve_test.dart b/tests/isolate/scenarios/automatic_resolution_root/package_resolve_test.dart
new file mode 100644
index 0000000..15eaa3e
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_root/package_resolve_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2015, 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.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final PACKAGE_URI = "package:foo/bar.dart";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   automaticPackageResolution: true);
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    var child_pkg_root = Platform.script.resolve("packages/");
+    if (msg[0] != child_pkg_root.toString()) {
+      throw "Bad package root in child isolate: ${msg[0]}.\n"
+            "Expected: $child_pkg_root";
+    }
+    var child_pkg_path = child_pkg_root.resolve("foo/bar.dart");
+    if (msg[1] != child_pkg_path.toString()) {
+      throw "Package path not matching: ${msg[1]}\n"
+            "Expected $child_pkg_path";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageRoot = await Isolate.packageRoot;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package root: $packageRoot");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageRoot?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/scenarios/automatic_resolution_root/packages/empty_file b/tests/isolate/scenarios/automatic_resolution_root/packages/empty_file
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_root/packages/empty_file
diff --git a/tests/isolate/scenarios/automatic_resolution_spec/.packages b/tests/isolate/scenarios/automatic_resolution_spec/.packages
new file mode 100644
index 0000000..79bcf43
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_spec/.packages
@@ -0,0 +1 @@
+foo:file:///no/such/directory/
diff --git a/tests/isolate/scenarios/automatic_resolution_spec/package_resolve_test.dart b/tests/isolate/scenarios/automatic_resolution_spec/package_resolve_test.dart
new file mode 100644
index 0000000..e34c5b3
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_spec/package_resolve_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2015, 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.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final PACKAGE_URI = "package:foo/bar.dart";
+final PACKAGE_PATH = "file:///no/such/directory/bar.dart";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   automaticPackageResolution: true);
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    var child_pkg_config = Platform.script.resolve(".packages");
+    if (msg[0] != child_pkg_config.toString()) {
+      throw "Bad package config in child isolate: ${msg[0]}\n"
+            "Expected: $child_pkg_config";
+    }
+    if (msg[1] != PACKAGE_PATH) {
+      throw "Package path not matching: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/spawn_uri_fail_test.dart b/tests/isolate/spawn_uri_fail_test.dart
new file mode 100644
index 0000000..659a798
--- /dev/null
+++ b/tests/isolate/spawn_uri_fail_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2016, 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.
+
+import "dart:io";
+import "dart:isolate";
+import "package:expect/expect.dart";
+
+main() async {
+  var pkgRoot = Uri.parse("file:///no/such/directory/");
+  var pkgConfig = Uri.parse("file:///no/such/.packages");
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageRoot: pkgRoot, packageConfig: pkgConfig);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageRoot: pkgRoot, automaticPackageResolution: true);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageConfig: pkgConfig, automaticPackageResolution: true);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageRoot: pkgRoot, packageConfig: pkgConfig,
+        automaticPackageResolution: true);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+}
diff --git a/tests/language/config_import_test.dart b/tests/language/config_import_test.dart
index 5678e8e..96cf3e3 100644
--- a/tests/language/config_import_test.dart
+++ b/tests/language/config_import_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false --conditional-directives
+// VMOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false --conditional-directives
 
 import 'package:expect/expect.dart';
 
diff --git a/tests/language/const_qq_test.dart b/tests/language/const_qq_test.dart
new file mode 100644
index 0000000..d1c1642
--- /dev/null
+++ b/tests/language/const_qq_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2015, 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.
+
+// Check that ?? is compile-time constant.
+
+import "package:expect/expect.dart";
+
+const theNull = null;
+const notNull = const Object();
+
+// Top-level const field initializer.
+const test1 = theNull ?? notNull;
+const test2 = notNull ?? theNull;
+const test3 = theNull ?? theNull ?? notNull;
+const test4 = theNull ?? theNull ?? theNull;
+
+class P {
+  final v;
+  const P(this.v);
+}
+
+// Annotation parameter (not checked by test!)
+@P(theNull ?? notNull)
+@P(notNull ?? theNull)
+@P(theNull ?? theNull ?? notNull)
+@P(theNull ?? theNull ?? theNull)
+class C {
+  // Static const field initializer.
+  static const test5 = theNull ?? notNull;
+  static const test6 = notNull ?? theNull;
+  static const test7 = theNull ?? theNull ?? notNull;
+  static const test8 = theNull ?? theNull ?? theNull;
+
+  // (Constructor) parameter defaults.
+  final test9;
+  final test10;
+  final test11;
+  final test12;
+
+  // Const constructor initializer list.
+  final test13;
+  final test14;
+  final test15;
+  final test16;
+  final test17;
+
+  const C(x,
+          [this.test9  = theNull ?? notNull,
+           this.test10 = notNull ?? theNull,
+           this.test11 = theNull ?? theNull ?? notNull,
+           this.test12 = theNull ?? theNull ?? theNull])
+      : test13 = theNull ?? x,
+        test14 = notNull ?? x,
+        test15 = x ?? notNull,
+        test16 = theNull ?? theNull ?? x,
+        test17 = theNull ?? x ?? notNull;
+
+  List methodLocal() {
+    // Method local const variable initializer.
+    const test18 = theNull ?? notNull;
+    const test19 = notNull ?? theNull;
+    const test20 = theNull ?? theNull ?? notNull;
+    const test21 = theNull ?? theNull ?? theNull;
+
+    return const [test18, test19, test20, test21];
+  }
+
+  List expressionLocal() {
+    // Constant expression sub-expression.
+    return const [theNull ?? notNull,
+                  notNull ?? theNull,
+                  theNull ?? theNull ?? notNull,
+                  theNull ?? theNull ?? theNull];
+  }
+}
+
+main() {
+  Expect.identical(notNull, test1, "test1");
+  Expect.identical(notNull, test2, "test2");
+  Expect.identical(notNull, test3, "test3");
+  Expect.identical(theNull, test4, "test4");
+
+  Expect.identical(notNull, C.test5, "test5");
+  Expect.identical(notNull, C.test6, "test6");
+  Expect.identical(notNull, C.test7, "test7");
+  Expect.identical(theNull, C.test8, "test8");
+
+  const c1 = const C(null);
+  Expect.identical(notNull, c1.test9, "test9");
+  Expect.identical(notNull, c1.test10, "test10");
+  Expect.identical(notNull, c1.test11, "test11");
+  Expect.identical(theNull, c1.test12, "test12");
+
+  Expect.identical(theNull, c1.test13, "test13");
+  Expect.identical(notNull, c1.test14, "test14");
+  Expect.identical(notNull, c1.test15, "test15");
+  Expect.identical(theNull, c1.test16, "test16");
+  Expect.identical(notNull, c1.test17, "test17");
+
+  var list = c1.methodLocal();
+  Expect.identical(notNull, list[0], "test18");
+  Expect.identical(notNull, list[1], "test19");
+  Expect.identical(notNull, list[2], "test20");
+  Expect.identical(theNull, list[3], "test21");
+
+  list = c1.expressionLocal();
+  Expect.identical(notNull, list[0], "test22");
+  Expect.identical(notNull, list[1], "test23");
+  Expect.identical(notNull, list[2], "test24");
+  Expect.identical(theNull, list[3], "test25");
+
+  const c2 = const C(42);
+  Expect.identical(notNull, c2.test9, "test26");
+  Expect.identical(notNull, c2.test10, "test27");
+  Expect.identical(notNull, c2.test11, "test28");
+  Expect.identical(theNull, c2.test12, "test29");
+
+  Expect.identical(42     , c2.test13, "test30");
+  Expect.identical(notNull, c2.test14, "test31");
+  Expect.identical(42     , c2.test15, "test32");
+  Expect.identical(42     , c2.test16, "test33");
+  Expect.identical(42     , c2.test17, "test34");
+
+  list = c2.methodLocal();
+  Expect.identical(notNull, list[0], "test35");
+  Expect.identical(notNull, list[1], "test36");
+  Expect.identical(notNull, list[2], "test37");
+  Expect.identical(theNull, list[3], "test38");
+
+  list = c2.expressionLocal();
+  Expect.identical(notNull, list[0], "test39");
+  Expect.identical(notNull, list[1], "test40");
+  Expect.identical(notNull, list[2], "test41");
+  Expect.identical(theNull, list[3], "test42");
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index b16b0c9..ec744b7 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -8,6 +8,7 @@
 [ ($compiler == none || $compiler == precompiler) ]
 built_in_identifier_prefix_test: Fail # Issue 6970
 tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
+const_qq_test: Fail
 
 # These bugs refer currently ongoing language discussions.
 constructor5_test: Fail # Issue 6422
@@ -37,9 +38,6 @@
 async_star_cancel_while_paused_test: RuntimeError
 async_star_await_pauses_test: Skip # Times out. Issue 23996
 
-# Unsupported configuration specific imports.
-config_import_test: Fail # Issue 24581
-
 [ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
@@ -72,7 +70,7 @@
 
 [ ($compiler == none || $compiler == precompiler) && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
 issue13474_test: Pass, Fail # Issue 14651.
-vm/optimized_guarded_field_isolates_test: Fail # Issue 13921.
+config_import_test: Fail # Issue 14651.
 main_test/01: Fail # Issue 20028
 main_test/02: Fail # Issue 20028
 main_test/04: Fail # Issue 20028
@@ -134,6 +132,7 @@
 vm/reflect_core_vm_test: CompileTimeError
 redirecting_factory_reflection_test: CompileTimeError
 deferred_constraints_constants_test: Skip # multitest gets confused
+vm/type_vm_test: RuntimeError # Expects line and column numbers
 
 # Deferred loading happens eagerly
 regress_23408_test: RuntimeError
@@ -144,7 +143,6 @@
 deopt_inlined_function_lazy_test: Pass, Crash # Incompatible flag: --deoptimize-alot
 tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
 vm/type_cast_vm_test: RuntimeError # Line number mismatch.
-stack_trace_test: Fail  # Issue 24783 - inlined frames missing
 
 [ $runtime == dart_precompiled ]
 ct_const2_test: Pass, Crash # Incompatible flag --compile_all
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 547ffb6..5ea3d0a 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -482,3 +482,5 @@
 # This test is expected to generate a warning, since it's
 # intentionally referring to a variable that's not in scope.
 transitive_private_library_access_test: StaticWarning
+
+const_qq_test: Fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 2ec0676..2dbad85 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -267,56 +267,10 @@
 await_for_test: Crash # (await for(var x in infiniteStream()){i++ ;if(i>10)break;t4.record(x);}): await for
 await_for_use_local_test: Crash # (await for(var v in s){accum+= v;}): await for
 call_closurization_test: RuntimeError # Bad type inference for ".call" tear-off.
-cha_deopt1_test: Crash # (d.make_u()): deferred access is not implemented
-cha_deopt2_test: Crash # (d.make_u()): deferred access is not implemented
-cha_deopt3_test: Crash # (d.make_u()): deferred access is not implemented
 closure_in_constructor_test: RuntimeError # Please triage this failure.
 closures_initializer_test: RuntimeError # Please triage this failure.
 constructor12_test: RuntimeError # Please triage this failure.
-deferred_call_empty_before_load_test: Crash # (lib1.thefun()): deferred access is not implemented
-deferred_closurize_load_library_test: RuntimeError # D.loadLibrary is not a function
-deferred_constant_list_test: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_constants_test/none: RuntimeError # S.loadLibrary is not a function
-deferred_constraints_constants_test/reference_after_load: RuntimeError # G.loadLibrary is not a function
-deferred_constraints_type_annotation_test/as_operation: RuntimeError # Z.loadLibrary is not a function
-deferred_constraints_type_annotation_test/catch_check: RuntimeError # D.loadLibrary is not a function
-deferred_constraints_type_annotation_test/is_check: RuntimeError # L.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new: RuntimeError # R.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_before_load: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_generic1: RuntimeError # R.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_generic2: RuntimeError # X.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_generic3: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_type_annotation_test/none: RuntimeError # D.loadLibrary is not a function
-deferred_constraints_type_annotation_test/static_method: RuntimeError # F.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation1: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic1: RuntimeError # T.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic2: RuntimeError # Q.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic3: RuntimeError # Z.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic4: RuntimeError # Q.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_non_deferred: RuntimeError # R.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_null: RuntimeError # Z.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_top_level: RuntimeError # U.loadLibrary is not a function
-deferred_function_type_test: RuntimeError # N.loadLibrary is not a function
-deferred_global_test: RuntimeError # Y.loadLibrary is not a function
-deferred_inlined_test: Crash # (lib.foo()): deferred access is not implemented
-deferred_load_constants_test/none: Crash # (foo.toplevel): deferred access is not implemented
-deferred_load_inval_code_test: Crash # (d.foo()): deferred access is not implemented
-deferred_load_library_wrong_args_test/none: RuntimeError # Y.loadLibrary is not a function
-deferred_mixin_test: RuntimeError # X.loadLibrary is not a function
-deferred_no_such_method_test: RuntimeError # D.loadLibrary is not a function
-deferred_not_loaded_check_test: Crash # (lib.closure(sideEffect())): deferred access is not implemented
-deferred_only_constant_test: RuntimeError # O.loadLibrary is not a function
-deferred_optimized_test: Crash # (lib.foo()): deferred access is not implemented
-deferred_redirecting_factory_test: Crash # (lib1.loadLib2()): deferred access is not implemented
-deferred_regression_22995_test: RuntimeError # U.loadLibrary is not a function
-deferred_shadow_load_library_test: RuntimeError # Y.loadLibrary is not a function
-deferred_shared_and_unshared_classes_test: RuntimeError # U.loadLibrary is not a function
-deferred_static_seperate_test: RuntimeError # L.loadLibrary is not a function
-deferred_super_dependency_test/01: RuntimeError # $async$temp1.loadLibrary is not a function
-deferred_type_dependency_test/as: Crash # (lib1.fooAs("string")): deferred access is not implemented
-deferred_type_dependency_test/is: Crash # (lib1.fooIs("string")): deferred access is not implemented
-deferred_type_dependency_test/none: Crash # (lib2.getInstance()): deferred access is not implemented
-deferred_type_dependency_test/type_annotation: Crash # (lib1.fooAnnotation("string")): deferred access is not implemented
+deferred_super_dependency_test/01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 field3a_negative_test: Fail # Bogus result from type inference in case of invalid program.
 first_class_types_test: RuntimeError # Please triage this failure.
 generic2_test: RuntimeError # Please triage this failure.
@@ -327,13 +281,10 @@
 instanceof2_test: RuntimeError # Please triage this failure.
 instanceof4_test/01: RuntimeError # Please triage this failure.
 invocation_mirror_test: Crash # (super[37]=42): visitUnresolvedSuperIndexSet
-issue_1751477_test: RuntimeError # O.loadLibrary is not a function
 list_is_test: RuntimeError # Please triage this failure.
 list_test: RuntimeError # Please triage this failure.
 many_generic_instanceof_test: RuntimeError # Please triage this failure.
 nested_switch_label_test: Crash # (switch (target){out...  continue to a labeled switch case
-regress_22443_test: RuntimeError # M.loadLibrary is not a function
-regress_23408_test: RuntimeError # G.loadLibrary is not a function
 regress_23500_test/01: Crash # (await for(var c in new Stream.fromIterable([] )){}): await for
 stack_trace_test: Fail # Stack trace not preserved when inlining?
 super_call4_test: RuntimeError # Please triage this failure.
@@ -346,13 +297,14 @@
 switch_label2_test: Crash # (switch (target){cas...  continue to a labeled switch case
 switch_label_test: Crash # (switch (animal){cas...  continue to a labeled switch case
 switch_try_catch_test: Crash # (switch (0){_0:case ...  continue to a labeled switch case
-type_variable_closure2_test: RuntimeError # Please triage this failure.
-type_variable_field_initializer_closure_test: RuntimeError # Please triage this failure.
-type_variable_field_initializer_test: RuntimeError # Please triage this failure.
-type_variable_nested_test: RuntimeError # Please triage this failure.
+type_variable_closure2_test: RuntimeError # Issue 25309: T lost in List<T>
+type_variable_closure4_test: RuntimeError # T lost in <T,T>{}
+type_variable_field_initializer_closure_test: RuntimeError # Issue 25309: T lost in List<T>
+type_variable_field_initializer_test: RuntimeError # Issue 25309: T lost in List<T>
+type_variable_nested_test: RuntimeError # Issue 25309: T lost in List<T>
 
 [ $compiler == dart2js && $cps_ir && $host_checked == false ]
-regress_21795_test: RuntimeError # Due to inlining?
+regress_21795_test: Pass, RuntimeError # Due to inlining?
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 async_throw_in_catch_test/forceAwait: Crash # Issue 24485
diff --git a/tests/language/try_finally_regress_25333_test.dart b/tests/language/try_finally_regress_25333_test.dart
new file mode 100644
index 0000000..1feb510
--- /dev/null
+++ b/tests/language/try_finally_regress_25333_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2016, 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.
+
+// Test correct handling of try-catch inside try-finally.
+
+import "package:expect/expect.dart";
+
+void main() {
+  print("== test1 ==");
+  bool caught = false;
+  try {
+    test1();
+    print("Unexpected 1"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 1: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+  print("== test2 ==");
+  caught = false;
+  try {
+    test2();
+    print("Unexpected 2"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 2: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+}
+
+void test1() {
+  try {
+    throw "Ball";
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch(e) {
+      print("test 1 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+void test2() {
+  try {
+    throwError(); // call a method that throws an error
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch(e) {
+      print("test 2 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+
+void throwError() {
+  throw "Ball";
+}
diff --git a/tests/language/type_variable_closure2_test.dart b/tests/language/type_variable_closure2_test.dart
index 1b55ff9..83e246b 100644
--- a/tests/language/type_variable_closure2_test.dart
+++ b/tests/language/type_variable_closure2_test.dart
@@ -7,25 +7,12 @@
 class A<T> {}
 
 class C<T> {
-  a() {
-    return () => new A<T>();
-  }
-
   list() {
     return () => <T>[];
   }
-
-  map() {
-    return () => <T, T>{};
-  }
 }
 
 main() {
-  Expect.isTrue(new C<int>().a()() is A<int>);
-  Expect.isFalse(new C<int>().a()() is A<String>);
   Expect.isTrue(new C<int>().list()() is List<int>);
   Expect.isFalse(new C<int>().list()() is List<String>);
-  Expect.isTrue(new C<int>().map()() is Map<int, int>);
-  Expect.isFalse(new C<int>().map()() is Map<String, int>);
-  Expect.isFalse(new C<int>().map()() is Map<int, String>);
 }
diff --git a/tests/language/type_variable_closure3_test.dart b/tests/language/type_variable_closure3_test.dart
new file mode 100644
index 0000000..ecb1c39
--- /dev/null
+++ b/tests/language/type_variable_closure3_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, 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.
+
+import "package:expect/expect.dart";
+
+class A<T> {}
+
+class C<T> {
+  a() {
+    return () => new A<T>();
+  }
+}
+
+main() {
+  Expect.isTrue(new C<int>().a()() is A<int>);
+  Expect.isFalse(new C<int>().a()() is A<String>);
+}
diff --git a/tests/language/type_variable_closure4_test.dart b/tests/language/type_variable_closure4_test.dart
new file mode 100644
index 0000000..e75bc08
--- /dev/null
+++ b/tests/language/type_variable_closure4_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, 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.
+
+import "package:expect/expect.dart";
+
+class A<T> {}
+
+class C<T> {
+  map() {
+    return () => <T, T>{};
+  }
+}
+
+main() {
+  Expect.isTrue(new C<int>().map()() is Map<int, int>);
+  Expect.isFalse(new C<int>().map()() is Map<String, int>);
+  Expect.isFalse(new C<int>().map()() is Map<int, String>);
+}
diff --git a/tests/language/type_variable_field_initializer2_test.dart b/tests/language/type_variable_field_initializer2_test.dart
new file mode 100644
index 0000000..098d9e3
--- /dev/null
+++ b/tests/language/type_variable_field_initializer2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, 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.
+
+// Check that an inlined field initializer has access to the enclosing
+// type variables.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  var c = new X<T>();
+}
+
+class B<T> extends A<T> {
+}
+
+class X<T> {}
+
+main() {
+  Expect.isTrue(new B<int>().c is X<int>);
+  Expect.isFalse(new B<String>().c is X<int>);
+}
diff --git a/tests/language/type_variable_field_initializer_closure2_test.dart b/tests/language/type_variable_field_initializer_closure2_test.dart
new file mode 100644
index 0000000..eaefd18
--- /dev/null
+++ b/tests/language/type_variable_field_initializer_closure2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, 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.
+
+// Check that an inlined field closure has access to the enclosing
+// type variables.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  var c = (() => new X<T>())();
+}
+
+class B<T> extends A<T> {
+}
+
+class X<T> {}
+
+main() {
+  Expect.isTrue(new B<int>().c is X<int>);
+  Expect.isFalse(new B<String>().c is X<int>);
+}
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 030340d..e8387bf 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -926,6 +926,74 @@
   testType("Future.error", new Future<int>.error("ERR")..catchError((_){}));
 }
 
+void testAnyValue() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.equals(42, v);
+    asyncEnd();
+  }, onError: (e, s) {
+    Expect.fail("Unexpected error: $e");
+  });
+
+  cs[1].complete(42);
+  cs[2].complete(10);
+  cs[0].complete(20);
+}
+
+void testAnyError() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.fail("Unexpected value: $v");
+  }, onError: (e, s) {
+    Expect.equals(42, e);
+    asyncEnd();
+  });
+
+  cs[1].completeError(42);
+  cs[2].complete(10);
+  cs[0].complete(20);
+}
+
+void testAnyIgnoreIncomplete() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.equals(42, v);
+    asyncEnd();
+  }, onError: (e, s) {
+    Expect.fail("Unexpected error: $e");
+  });
+
+  cs[1].complete(42);
+  // The other two futures never complete.
+}
+
+void testAnyIgnoreError() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.equals(42, v);
+    asyncEnd();
+  }, onError: (e, s) {
+    Expect.fail("Unexpected error: $e");
+  });
+
+  cs[1].complete(42);
+  // The errors are ignored, not uncaught.
+  cs[2].completeError("BAD");
+  cs[0].completeError("BAD");
+}
+
 main() {
   asyncStart();
 
@@ -989,6 +1057,11 @@
 
   testTypes();
 
+  testAnyValue();
+  testAnyError();
+  testAnyIgnoreIncomplete();
+  testAnyIgnoreError();
+
   asyncEnd();
 }
 
diff --git a/tests/lib/async/stream_from_futures_test.dart b/tests/lib/async/stream_from_futures_test.dart
new file mode 100644
index 0000000..e4eaef5
--- /dev/null
+++ b/tests/lib/async/stream_from_futures_test.dart
@@ -0,0 +1,130 @@
+// 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.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
+
+main() {
+  asyncStart();
+
+  testValues();
+  testErrors();
+  testMixed();
+  testOrdering();
+  testEmpty();
+  testPrecompleted();
+
+  asyncEnd();
+}
+
+void testValues() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var stream = new Stream.fromFutures(cs.map((x) => x.future));
+  var result = stream.toList();
+
+  result.then((list) {
+    Expect.listEquals([1, 2, 3], list);
+    asyncEnd();
+  });
+
+  cs[1].complete(1);
+  cs[2].complete(2);
+  cs[0].complete(3);
+}
+
+void testErrors() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var stream = new Stream.fromFutures(cs.map((x) => x.future));
+
+  int counter = 0;
+  stream.listen((_) {
+    Expect.fail("unexpected value");
+  }, onError: (e) {
+    Expect.equals(++counter, e);
+  }, onDone: () {
+    Expect.equals(3, counter);
+    asyncEnd();
+  });
+
+  cs[1].completeError(1);
+  cs[2].completeError(2);
+  cs[0].completeError(3);
+}
+
+void testMixed() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var stream = new Stream.fromFutures(cs.map((x) => x.future));
+
+  int counter = 0;
+  stream.listen((v) {
+    Expect.isTrue(counter == 0 || counter == 2);
+    Expect.equals(++counter, v);
+  }, onError: (e) {
+    Expect.equals(++counter, 2);
+    Expect.equals(2, e);
+  }, onDone: () {
+    Expect.equals(3, counter);
+    asyncEnd();
+  });
+
+  cs[1].complete(1);
+  cs[2].completeError(2);
+  cs[0].complete(3);
+}
+
+void testOrdering() {
+  // The output is in completion order, not affected by the input future order.
+  test(n1, n2, n3) {
+    asyncStart();
+    var cs = new List.generate(3, (_) => new Completer());
+    var stream = new Stream.fromFutures(cs.map((x) => x.future));
+    var result = stream.toList();
+
+    result.then((list) {
+      Expect.listEquals([1, 2, 3], list);
+      asyncEnd();
+    });
+
+    cs[n1].complete(1);
+    cs[n2].complete(2);
+    cs[n3].complete(3);
+  }
+  test(0, 1, 2);
+  test(0, 2, 1);
+  test(1, 0, 2);
+  test(1, 2, 0);
+  test(2, 0, 1);
+  test(2, 1, 0);
+}
+
+void testEmpty() {
+  asyncStart();
+  var stream = new Stream.fromFutures([]);
+
+  stream.listen((_) {
+    Expect.fail("unexpected value");
+  }, onError: (e) {
+    Expect.fail("unexpected error");
+  }, onDone: () {
+    asyncEnd();
+  });
+}
+
+void testPrecompleted() {
+  asyncStart();
+  var stream = new Stream.fromFutures(
+      new Iterable.generate(3, (v) => new Future.value(v + 1)));
+  var expected = new Set.from([1, 2, 3]);
+  stream.listen((v) {
+    Expect.isTrue(expected.contains(v));
+    expected.remove(v);
+  }, onDone: () {
+    Expect.isTrue(expected.isEmpty);
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 5a8dcdb..d4cdafe 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -341,12 +341,7 @@
 [ $compiler == dart2js && $cps_ir ]
 async/async_await_zones_test: Crash # (await for(var x in bar().take(100)){sum+= x;}): await for
 async/stream_iterator_test: Crash # (Stream createCancel...  cannot handle sync*/async* functions
-mirrors/deferred_mirrors_metadata_test: RuntimeError # U.loadLibrary is not a function
-mirrors/deferred_mirrors_metatarget_test: RuntimeError # X.loadLibrary is not a function
-mirrors/deferred_mirrors_update_test: RuntimeError # U.loadLibrary is not a function
-mirrors/library_enumeration_deferred_loading_test: RuntimeError # L.loadLibrary is not a function
 mirrors/symbol_validation_test/none: RuntimeError # Please triage this failure.
-mirrors/typedef_deferred_library_test: RuntimeError # G.loadLibrary is not a function
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 mirrors/circular_factory_redirection_test/02: Crash # Assertion failure: Constant constructor already computed for generative_constructor(A#circular2)
diff --git a/tests/lib/mirrors/library_exports_hidden_test.dart b/tests/lib/mirrors/library_exports_hidden_test.dart
index 990dbb1..cdfe5fe 100644
--- a/tests/lib/mirrors/library_exports_hidden_test.dart
+++ b/tests/lib/mirrors/library_exports_hidden_test.dart
@@ -2,7 +2,7 @@
 // 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 test.library_imports;
+library test.library_exports_hidden;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_exports_shown_test.dart b/tests/lib/mirrors/library_exports_shown_test.dart
index 66592f1..4cdded1 100644
--- a/tests/lib/mirrors/library_exports_shown_test.dart
+++ b/tests/lib/mirrors/library_exports_shown_test.dart
@@ -2,7 +2,7 @@
 // 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 test.library_imports;
+library test.library_exports_shown;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_hidden_test.dart b/tests/lib/mirrors/library_imports_hidden_test.dart
index 3f1dcb0..7d08e1f 100644
--- a/tests/lib/mirrors/library_imports_hidden_test.dart
+++ b/tests/lib/mirrors/library_imports_hidden_test.dart
@@ -2,7 +2,7 @@
 // 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 test.library_imports;
+library test.library_imports_hidden;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
index eb865a1..d18f361 100644
--- a/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
+++ b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
@@ -2,7 +2,7 @@
 // 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 test.library_imports;
+library test.library_imports_prefixed_show_hide;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_prefixed_test.dart b/tests/lib/mirrors/library_imports_prefixed_test.dart
index beda171..1db1799 100644
--- a/tests/lib/mirrors/library_imports_prefixed_test.dart
+++ b/tests/lib/mirrors/library_imports_prefixed_test.dart
@@ -2,7 +2,7 @@
 // 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 test.library_imports;
+library test.library_imports_prefixed;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_shown_test.dart b/tests/lib/mirrors/library_imports_shown_test.dart
index fb16df2..208e570 100644
--- a/tests/lib/mirrors/library_imports_shown_test.dart
+++ b/tests/lib/mirrors/library_imports_shown_test.dart
@@ -2,7 +2,7 @@
 // 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 test.library_imports;
+library test.library_imports_shown;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 6dbdcd4..1c84cd5 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -296,6 +296,8 @@
     "  attachment  ;filename=genome.jpeg  ;"
     "modification-date = \"Wed, 12 February 1997 16:29:51 -0500\""  );
   check(headerValue, "attachment", parameters);
+  headerValue = HeaderValue.parse("xxx; aaa; bbb; ccc");
+  check(headerValue, "xxx", {"aaa": null, "bbb": null, "ccc": null});
 }
 
 void testContentType() {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 948099d..19b2d431 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -11,7 +11,9 @@
 package/scenarios/packages_file_strange_formatting/empty_package_dir_test: Fail, OK # CompileTimeErrors intentionally
 package/scenarios/empty_packages_file/empty_packages_file_discovery_test: Fail, OK # CompileTimeErrors intentionally
 package/scenarios/empty_packages_file/empty_packages_file_option_test: Fail, OK # CompileTimeErrors intentionally
-package/scenarios/invalid/*: Fail, OK # CompileTimeErrors intentionally
+package/scenarios/invalid/invalid_package_name_test: RuntimeError, CompileTimeError # Errors intentionally
+package/scenarios/invalid/same_package_twice_test.dart: RuntimeError, CompileTimeError # Errors intentionally
+
 
 issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
 
@@ -45,8 +47,6 @@
 io/socket_many_connections_test: Skip
 
 [ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
-typed_array_test: Fail # Issue 13921
-typed_array_int64_uint64_test: Fail # Issue 13921
 typed_data_isolate_test: SkipByDesign # This test uses dart:io
 io/*: SkipByDesign # Don't run tests using dart:io in the browser
 package/*: Skip # Do not run those in Dartium.
@@ -89,6 +89,7 @@
 package/package_isolate_test: Skip # spawnUri does not work in dart2js. See issue 3051
 package/package_test: Fail, OK # dart2js does not support 'package:foo.dart' imports
 package/package1_test: Fail, OK # dart2js does not support 'package:foo.dart' imports
+package/scenarios/invalid/*: CompileTimeError  # Negative tests expecting CompileTimeErrors.
 full_coverage_test: Skip
 left_shift_bit_and_op_test: Skip # Integers exceed dart2js precision.
 pow_test: Skip # Precision > 53 bits.
@@ -222,6 +223,7 @@
 map_literal_oom_test: Pass, Crash # Issue 24678
 javascript*: SkipByDesign # JS overflow flag unsupported
 io/web_socket_test: Pass, RuntimeError # Issue 24674
+assert_test: RuntimeError # Expects line and column numbers
 
 [ $runtime == dart_precompiled ]
 debugger/*: Skip
diff --git a/tools/VERSION b/tools/VERSION
index d53b55e..c28a186 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 14
 PATCH 0
-PRERELEASE 6
+PRERELEASE 7
 PRERELEASE_PATCH 0
diff --git a/tools/build.py b/tools/build.py
index 0c5e235..dac178f 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -153,8 +153,10 @@
   if arch == 'arm':
     # To use a non-hf compiler, specify on the command line with --toolchain.
     return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/arm-linux-gnueabihf")
+  if arch == 'arm64':
+    return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/aarch64-linux-gnu")
 
-  # TODO(zra): Find default MIPS and ARM64 Linux cross-compilers.
+  # TODO(zra): Find default MIPS Linux cross-compiler.
 
   return None
 
diff --git a/tools/dartium/update_deps.py b/tools/dartium/update_deps.py
index a8b1b4b..6e27437 100755
--- a/tools/dartium/update_deps.py
+++ b/tools/dartium/update_deps.py
@@ -79,14 +79,14 @@
 # used to generated the commit message.
 REPOSITORY_INFO = {
     'webkit': (
-        'http://src.chromium.org/blink/branches/%s',
-        'http://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
+        'https://src.chromium.org/blink/branches/%s',
+        'https://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
     'blink': (
-        'http://src.chromium.org/blink/branches/%s',
-        'http://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
+        'https://src.chromium.org/blink/branches/%s',
+        'https://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
     'chromium': (
-        'http://src.chromium.org/chrome/branches/%s',
-        'http://src.chromium.org/viewvc/chrome?view=rev&revision=%s'),
+        'https://src.chromium.org/chrome/branches/%s',
+        'https://src.chromium.org/viewvc/chrome?view=rev&revision=%s'),
 }
 
 REPOSITORIES = REPOSITORY_INFO.keys()
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 135dd34..fbb0e6b 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -14,7 +14,7 @@
   "dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
   "chromium_base_revision": "297060",
   "dartium_webkit_branch": "/blink/branches/dart/dartium",
-  "dartium_webkit_revision": "202728",
+  "dartium_webkit_revision": "202748",
 
   # We use mirrors of all github repos to guarantee reproducibility and
   # consistency between what users see and what the bots see.
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 191d2db..61fc715 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -22,7 +22,9 @@
   }
 $endif
 
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
   @DomName('Document.caretRangeFromPoint')
+  @Unstable()
   Range caretRangeFromPoint(int x, int y) {
     return _caretRangeFromPoint(x, y);
   }
diff --git a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
index b9fd424..bf7bd07 100644
--- a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
@@ -9,9 +9,24 @@
   factory $CLASSNAME(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
+
+$if DART2JS
+    var options = {
+      'canBubble' : canBubble,
+      'cancelable' : cancelable,
+      'oldURL': oldUrl,
+      'newURL': newUrl,
+    };
+    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)',
+        type, convertDartToNative_Dictionary(options));
+$else
+    // TODO(alanknight): This is required while we're on Dartium 39, but will need
+    // to look like dart2js with later versions when initHashChange is removed.
     var event = document._createEvent("HashChangeEvent");
     event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
+$endif
   }
+
 $!MEMBERS
 }
diff --git a/tools/task_kill.py b/tools/task_kill.py
index 4a54965..ab07e8a 100755
--- a/tools/task_kill.py
+++ b/tools/task_kill.py
@@ -206,7 +206,11 @@
   options = GetOptions()
   status = 0
   if options.kill_dart:
-    status += KillDart()
+    if os_name == "win32":
+      # TODO(24086): Add result of KillDart into status once pub hang is fixed.
+      KillDart()
+    else:
+      status += KillDart()
   if options.kill_fletch:
     status += KillFletch()
   if options.kill_vc:
diff --git a/tools/testing/perf_testing/appengine/app.yaml b/tools/testing/perf_testing/appengine/app.yaml
deleted file mode 100644
index 3fd8832..0000000
--- a/tools/testing/perf_testing/appengine/app.yaml
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) 2011, 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.
-
-application: google.com:dartperf
-version: 1
-runtime: python
-api_version: 1
-
-handlers:
-- url: /(.*\.html)
-  mime_type: text/html
-  static_files: static/\1
-  upload: static/(.*\.html)
-
-- url: /(.*\.js)
-  mime_type: text/javascript
-  static_files: static/\1
-  upload: static/(.*\.js)
-
-- url: /(.*\.txt)
-  mime_type: text/html
-  static_files: static/\1
-  upload: static/(.*\.txt)
-
-- url: /(.*\.json)
-  mime_type: application/json
-  static_files: static/\1
-  upload: static/(.*\.json)
-
-# image files
-- url: /(.*\.(bmp|gif|ico|jpeg|jpg|png))
-  static_files: static/\1
-  upload: static/(.*\.(bmp|gif|ico|jpeg|jpg|png))
-
-# index files
-- url: /(.+)/
-  static_files: static/\1/index.html
-  upload: static/(.+)/index.html
-  expiration: "15m"
-
-- url: /(.+)
-  static_files: static/\1/index.html
-  upload: static/(.+)/index.html
-  expiration: "15m"
-
-- url: /graphs
-  static_dir: static/graphs
-
-- url: /graphs/(.*)
-  static_files: static/graphs/\1
-  upload: static/graphs/(.*)
-
-- url: /data/browser-perf/macos/(.*)
-  static_files: static/data/browser-perf/macos/\1
-  upload: static/data/browser-perf/macos/(.*)
-
-- url: /data/code-time-size/macos/(.*)
-  static_files: static/data/code-time-size/macos/\1
-  upload: static/data/code-time-size/macos/(.*)
-
-- url: /data/cl-results/macos/(.*)
-  static_files: static/data/cl-results/macos/\1
-  upload: static/data/cl-results/macos/(.*)
-
-# site root
-- url: /
-  static_files: static/index.html
-  upload: static/index.html
-  expiration: "15m"
diff --git a/tools/testing/perf_testing/calc_and_send_mail.py b/tools/testing/perf_testing/calc_and_send_mail.py
deleted file mode 100644
index 090b70e..0000000
--- a/tools/testing/perf_testing/calc_and_send_mail.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2011, 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.
-
-import create_graph
-from create_graph import BROWSER_CORRECTNESS
-from create_graph import BROWSER_PERF
-from create_graph import CL_PERF
-from create_graph import COMMAND_LINE
-from create_graph import CORRECTNESS
-from create_graph import FROG
-from create_graph import FROG_MEAN
-from create_graph import TIME_SIZE
-from create_graph import V8_AND_FROG
-
-import get_current_stats
-import os
-from os.path import dirname, abspath
-import pickle
-import sys
-
-"""Compare the current performance statistics with the statistics 24 hours ago,
-and send out an email summarizing the differences."""
-
-def calculate_stats():
-  """Compare the numbers that were available at the start of the day to what the
-  current numbers are.
-
-  Returns:
-    A string providing an update on the latest perfromance numbers."""
-  test_runner_dict = pickle.load(open(get_current_stats.PICKLE_FILENAME, 'r'))
-  test_runner_dict = get_current_stats.populate_stats_dict(test_runner_dict)
-
-  browser_perf = test_runner_dict[BROWSER_PERF]
-  time_size = test_runner_dict[TIME_SIZE]
-  cl = test_runner_dict[CL_PERF]
-  correctness = test_runner_dict[BROWSER_CORRECTNESS]
-  output = summary_stats(browser_perf, time_size, cl, correctness)
-  output += specific_stats(browser_perf, time_size, cl)
-  return output
-
-def summary_stats(browser_perf, time_size, cl, correctness):
-  """Return the summarized stats report.
-
-  Args:
-    browser_perf: BrowserPerformanceTestRunner object. Holds browser perf stats.
-    time_size: CompileTimeSizeTestRunner object. 
-    cl: CommandLinePerformanceTestRunner object.
-    correctness: BrowserCorrectnessTestRunner object.
-  """
-  output = "Summary of changes in the last 24 hours: \n\nBrowser " + \
-      "performance: (revision %d)\n" % \
-      browser_perf.revision_dict[create_graph.get_browsers()[0]][FROG]\
-      [browser_perf.values_list[0]][1]
-  for browser in create_graph.get_browsers():
-    geo_mean_list = browser_perf.values_dict[browser][FROG][FROG_MEAN]
-    # TODO(efortuna): deal with the fact that the latest of all browsers may not
-    # be available.
-    output += "  %s%s\n" % ((browser + ':').ljust(25), 
-        str(geo_mean_list[1] - geo_mean_list[0]).rjust(10))
-
-  output += "\nCompile Size and Time: (revision %d)\n" % \
-      time_size.revision_dict[COMMAND_LINE][FROG][time_size.values_list[0]][1]
-  for metric in time_size.values_list:
-    metric_list = time_size.values_dict[COMMAND_LINE][FROG][metric]
-    output += "  %s%s\n" % ((metric + ':').ljust(25), 
-        str(metric_list[1] - metric_list[0]).rjust(10))
-
-  output += "\nPercentage of language tests passing (revision %d)\n" % \
-      correctness.revision_dict['chrome'][FROG][correctness.values_list[0]][1]
-  for browser in create_graph.get_browsers():
-    num_correct = correctness.values_dict[browser][FROG][CORRECTNESS]
-    output += "  %s%s%%  more passing\n" % ((browser + ':').ljust(25), 
-        str(num_correct[1] - num_correct[0]).rjust(10))
-
-  output += "\nCommandline performance: (revision %d)\n" % \
-      cl.revision_dict[COMMAND_LINE][FROG][cl.values_list[0]][1]
-  for benchmark in cl.values_list:
-    bench_list = cl.values_dict[COMMAND_LINE][FROG][benchmark]
-    output += "  %s%s\n" % ((benchmark + ':').ljust(25), 
-        str(bench_list[1] - bench_list[0]).rjust(10))
-  return output
-
-def specific_stats(browser_perf, time_size, cl):
-  """Return a string detailing all of the gory details and specifics on 
-  benchmark numbers and individual benchmark changes.
-
-  Args:
-    browser_perf: BrowserPerformanceTestRunner object. Holds browser perf stats.
-    time_size: CompileTimeSizeTestRunner object. 
-    cl: CommandLinePerformanceTestRunner object.
-  """
-  output = "\n\n---------------------------------------------\nThe latest " + \
-      "current raw numbers (and changes) for those " + \
-      "interested:\nBrowser performance:\n"
-  for v8_or_frog in V8_AND_FROG:
-    for browser in create_graph.get_browsers():
-      output += "  %s %s:\n" % (browser, v8_or_frog)
-      for benchmark in create_graph.get_benchmarks():
-        bench_list = browser_perf.values_dict[browser][v8_or_frog][benchmark]
-        output += "    %s %s%s\n" % ((benchmark + ':').ljust(25), 
-            str(bench_list[1]).rjust(10), get_amount_changed(bench_list))
-
-  output += "\nCompile Size and Time for frog:\n" 
-  for metric in time_size.values_list:
-    metric_list = time_size.values_dict[COMMAND_LINE][FROG][metric]
-    output += "    %s %s%s\n" % ((metric + ':').ljust(25), 
-        str(metric_list[1]).rjust(10), get_amount_changed(metric_list))
-
-  output += "\nCommandline performance:\n"
-  for v8_or_frog in V8_AND_FROG:
-    output += '  %s:\n' % v8_or_frog
-    for benchmark in cl.values_list:
-      bench_list = cl.values_dict[COMMAND_LINE][v8_or_frog][benchmark]
-      output += "    %s %s%s\n" % ((benchmark + ':').ljust(25), 
-          str(bench_list[1]).rjust(10), get_amount_changed(bench_list))
-
-  return output
-
-def get_amount_changed(values_tuple):
-  """Return a formatted string indicating the amount of change (positive or
-  negative) in the benchmark since the last run.
-
-  Args:
-    values_tuple: the tuple of values we are comparing the difference 
-    between."""
-  difference = values_tuple[1] - values_tuple[0]
-  prefix = '+' 
-  if difference < 0:
-    prefix = '-'
-  return ("(%s%s)" % (prefix, str(difference))).rjust(10)
-
-
-def main():
-  stats = calculate_stats()
-  print stats
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/testing/perf_testing/data.html b/tools/testing/perf_testing/data.html
deleted file mode 100644
index daa8ba9..0000000
--- a/tools/testing/perf_testing/data.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>raw data</title>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-</head>
-<body>
-  <ul>
-    <li><a href="browser-perf-macos.html">Mac Browser Performance</a></li>
-    <li><a href="browser-perf-win32.html">Windows Browser Performance
-          (data not available yet)</a></li>
-    <li><a href="cl-results-macos.html">Mac Command Line Performance</a></li>
-    <li><a href="code-time-size-macos.html">Mac Compilation Time and Output Size</a></li>
-  </ul>
-</body>
-</html>
diff --git a/tools/testing/perf_testing/dromaeo.html b/tools/testing/perf_testing/dromaeo.html
deleted file mode 100644
index aee032d..0000000
--- a/tools/testing/perf_testing/dromaeo.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>Dart DOM metrics</title>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-</head>
-<body>
-<p><a href="data.html">Raw Data Logs</a></p>
-<img src="graphs/avg2dromaeo.png" />
-<img src="graphs/avg3dromaeo.png" />
-<img src="graphs/avg4dromaeo.png" />
-<img src="graphs/avg5dromaeo.png" />
-<img src="graphs/avg6dromaeo.png" />
-<img src="graphs/2dromaeo-size.png" />
-<br />
-
-<hr />
-
-<p> Individual Dromaeo benchmark performance </p>
-
-<p> Attributes benchmarks: </p>
-<img src="graphs/getAttributedromaeo.png" />
-<img src="graphs/element.propertydromaeo.png" />
-<img src="graphs/setAttributedromaeo.png" />
-<img src="graphs/element.property_ASSIGN_valuedromaeo.png" />
-
-<p> Modify benchmarks: </p>
-<img src="graphs/createElementdromaeo.png" />
-<img src="graphs/createTextNodedromaeo.png" />
-<img src="graphs/innerHTMLdromaeo.png" />
-<img src="graphs/cloneNodedromaeo.png" />
-<img src="graphs/appendChilddromaeo.png" />
-<img src="graphs/insertBeforedromaeo.png" />
-
-<p> Query benchmarks: </p>
-<img src="graphs/getElementByIddromaeo.png" />
-<img src="graphs/getElementById__not_in_document_dromaeo.png" />
-<img src="graphs/getElementsByTagName_div_dromaeo.png" />
-<img src="graphs/getElementsByTagName_p_dromaeo.png" />
-<img src="graphs/getElementsByTagName_a_dromaeo.png" />
-<img src="graphs/getElementsByTagName_ALL_dromaeo.png" />
-<img src="graphs/getElementsByTagName__not_in_document_dromaeo.png" />
-<img src="graphs/getElementsByNamedromaeo.png" />
-<img src="graphs/getElementsByName__not_in_document_dromaeo.png" />
-
-<p> Traverse benchmarks: </p>
-<img src="graphs/firstChilddromaeo.png" />
-<img src="graphs/lastChilddromaeo.png" />
-<img src="graphs/nextSiblingdromaeo.png" />
-<img src="graphs/previousSiblingdromaeo.png" />
-<img src="graphs/childNodesdromaeo.png" />
-
-</body>
-</html>
diff --git a/tools/testing/perf_testing/get_current_stats.py b/tools/testing/perf_testing/get_current_stats.py
deleted file mode 100644
index 4481501..0000000
--- a/tools/testing/perf_testing/get_current_stats.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2011, 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.
-
-from create_graph import BROWSER_CORRECTNESS
-from create_graph import BrowserCorrectnessTest
-from create_graph import BROWSER_PERF
-from create_graph import BrowserPerformanceTest
-from create_graph import CL_PERF
-from create_graph import CommandLinePerformanceTest
-from create_graph import CompileTimeAndSizeTest
-from create_graph import TIME_SIZE
-
-import os
-from os.path import dirname, abspath
-import pickle
-import re
-import sys
-
-"""Find the most recent performance files, and store the stats."""
-
-# TODO(efortuna): turn these into proper appengine tasks, using the app engine 
-# datastore instead of files.
-
-DIRECTORIES = [BROWSER_CORRECTNESS, BROWSER_PERF, CL_PERF, TIME_SIZE]
-PICKLE_FILENAME = 'start_stats.txt'
-
-def find_latest_data_files(directory):
-  """Given a directory, find the files with the latest timestamp, indicating the
-  latest results.
-
-  Args:
-    directory: name of the directory we should look inside.
-
-  Returns:
-    A list of the most recent files in the particular directory."""
-  path = dirname(abspath(__file__))
-  files = os.listdir(os.path.join(path, directory))
-  files.sort()
-  f = files.pop()
-  match = re.search('[1-9]', f)
-  trace_name = f[:match.start()]
-  timestamp_and_data = f[match.start():]
-  latest_files = [f]
-  if trace_name == 'correctness' or trace_name == 'perf-':
-    index = timestamp_and_data.find('-')
-    timestamp = timestamp_and_data[:index]
-    f = files.pop()
-    while f[match.start() : match.start() + index] == timestamp:
-      latest_files.append(f)
-      f = files.pop()
-  return latest_files
-
-def populate_stats_dict(test_runner_dict = None):
-  """Find the latest files in each directory, and process those latest files
-  using the appropriate TestRunner.
-
-  Args:
-    test_runner_dict: Optional agument storing previous data in runners to which
-    we should add our data."""
-  cur_runner_dict = dict()
-  if test_runner_dict:
-    cur_runner_dict = test_runner_dict
-  for directory in DIRECTORIES:
-    test_runner = None
-    latest_files = find_latest_data_files(directory)
-    
-    if test_runner_dict:
-      test_runner = cur_runner_dict[directory]
-    else:
-      if directory == BROWSER_CORRECTNESS:
-        test_runner = BrowserCorrectnessTest('language', directory)
-      elif directory == BROWSER_PERF:
-        test_runner = BrowserPerformanceTest(directory)
-      elif directory == TIME_SIZE:
-        test_runner = CompileTimeAndSizeTest(directory)
-      elif directory == CL_PERF:
-        test_runner = CommandLinePerformanceTest(directory)
-      cur_runner_dict[directory] = test_runner
-    
-    for f in latest_files:
-      test_runner.process_file(f)
-  return cur_runner_dict
-
-def main():
-  test_runner_dict = populate_stats_dict()
-  f = open(PICKLE_FILENAME, 'w')
-  pickle.dump(test_runner_dict, f)
-  f.close()
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/testing/perf_testing/index.html b/tools/testing/perf_testing/index.html
deleted file mode 100644
index 171dab1..0000000
--- a/tools/testing/perf_testing/index.html
+++ /dev/null
@@ -1,100 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>frog metrics</title>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-</head>
-<body>
-<p><a href="data.html">Raw Data Logs</a></p>
-
-<p><a href="dromaeo.html">Dromaeo Results</a></p>
-
-<img src="graphs/avg2browser-perf.png" />
-<img src="win/avg2browser-perf.png" />
-<img src="graphs/code-time-size.png" />
-<img src="graphs/2code-time-size.png" />
-<img src="graphs/avg2cl-results.png" />
-<img src="graphs/avg2dromaeo.png" />
-<img src="graphs/2dromaeo-size.png" />
-<br />
-
-<hr />
-
-<p> Individual benchmark performance in the Browser on Mac:</p>
-
-<img src="graphs/Fannkuchbrowser-perf.png" />
-<img src="graphs/NBodybrowser-perf.png" />
-<img src="graphs/Richardsbrowser-perf.png" />
-<img src="graphs/Towersbrowser-perf.png" />
-<img src="graphs/Fibonaccibrowser-perf.png" />
-<img src="graphs/Permutebrowser-perf.png" />
-<img src="graphs/Sievebrowser-perf.png" />
-<img src="graphs/TreeSortbrowser-perf.png" />
-<img src="graphs/BinaryTreesbrowser-perf.png" />
-<img src="graphs/Loopbrowser-perf.png" />
-<img src="graphs/Queensbrowser-perf.png" />
-<img src="graphs/Sumbrowser-perf.png" />
-<img src="graphs/BubbleSortbrowser-perf.png" />
-<img src="graphs/Mandelbrotbrowser-perf.png" />
-<img src="graphs/QuickSortbrowser-perf.png" />
-<img src="graphs/browser-perf.png" />
-<img src="graphs/DeltaBluebrowser-perf.png" />
-<img src="graphs/Meteorbrowser-perf.png" />
-<img src="graphs/Recursebrowser-perf.png" />
-<img src="graphs/Taklbrowser-perf.png" />
-<img src="graphs/Takbrowser-perf.png" />
-
-<hr />
-<p> Individual benchmark performance in the Browser on Windows:</p>
-
-<img src="win/Fannkuchbrowser-perf.png" />
-<img src="win/NBodybrowser-perf.png" />
-<img src="win/Richardsbrowser-perf.png" />
-<img src="win/Towersbrowser-perf.png" />
-<img src="win/Fibonaccibrowser-perf.png" />
-<img src="win/Permutebrowser-perf.png" />
-<img src="win/Sievebrowser-perf.png" />
-<img src="win/TreeSortbrowser-perf.png" />
-<img src="win/BinaryTreesbrowser-perf.png" />
-<img src="win/Loopbrowser-perf.png" />
-<img src="win/Queensbrowser-perf.png" />
-<img src="win/Sumbrowser-perf.png" />
-<img src="win/BubbleSortbrowser-perf.png" />
-<img src="win/Mandelbrotbrowser-perf.png" />
-<img src="win/QuickSortbrowser-perf.png" />
-<img src="win/browser-perf.png" />
-<img src="win/DeltaBluebrowser-perf.png" />
-<img src="win/Meteorbrowser-perf.png" />
-<img src="win/Recursebrowser-perf.png" />
-<img src="win/Taklbrowser-perf.png" />
-<img src="win/Takbrowser-perf.png" />
-
-<hr />
-<p> Individual Command Line benchmark performance: </p>
-
-<img src="graphs/Fannkuchcl-results.png" />
-<img src="graphs/NBodycl-results.png" />
-<img src="graphs/Richardscl-results.png" />
-<img src="graphs/Towerscl-results.png" />
-<img src="graphs/3code-time-size.png" />
-<img src="graphs/Fibonaccicl-results.png" />
-<img src="graphs/Permutecl-results.png" />
-<img src="graphs/Sievecl-results.png" />
-<img src="graphs/TreeSortcl-results.png" />
-<img src="graphs/BinaryTreescl-results.png" />
-<img src="graphs/Loopcl-results.png" />
-<img src="graphs/Queenscl-results.png" />
-<img src="graphs/Sumcl-results.png" />
-<img src="graphs/BubbleSortcl-results.png" />
-<img src="graphs/Mandelbrotcl-results.png" />
-<img src="graphs/QuickSortcl-results.png" />
-<img src="graphs/Takcl-results.png" />
-<img src="graphs/cl-results.png" />
-<img src="graphs/DeltaBluecl-results.png" />
-<img src="graphs/Meteorcl-results.png" />
-<img src="graphs/Recursecl-results.png" />
-<img src="graphs/Taklcl-results.png" />
-<img src="graphs/code-time-size.png" />
-</body>
-</html>
diff --git a/tools/testing/perf_testing/run_perf_tests.py b/tools/testing/perf_testing/run_perf_tests.py
deleted file mode 100755
index 194bbbc..0000000
--- a/tools/testing/perf_testing/run_perf_tests.py
+++ /dev/null
@@ -1,1087 +0,0 @@
-#!/usr/bin/python
-
-# 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.
-
-import datetime
-import math
-import optparse
-import os
-from os.path import dirname, abspath
-import pickle
-import platform
-import random
-import re
-import shutil
-import stat
-import subprocess
-import sys
-import time
-
-TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__)))))
-TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
-                                             '..'))
-DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
-                                             '..', '..', '..',
-                                             'dart_checkout_for_perf_testing',
-                                             'dart'))
-# How far back in time we want to test.
-EARLIEST_REVISION = 33076
-sys.path.append(TOOLS_PATH)
-sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests'))
-import post_results
-import utils
-
-"""This script runs to track performance and size progress of
-different svn revisions. It tests to see if there a newer version of the code on
-the server, and will sync and run the performance tests if so."""
-class TestRunner(object):
-
-  def __init__(self):
-    self.verbose = False
-    self.has_shell = False
-    if platform.system() == 'Windows':
-      # On Windows, shell must be true to get the correct environment variables.
-      self.has_shell = True
-    self.current_revision_num = None
-
-  def RunCmd(self, cmd_list, outfile=None, append=False, std_in=''):
-    """Run the specified command and print out any output to stdout.
-
-    Args:
-      cmd_list: a list of strings that make up the command to run
-      outfile: a string indicating the name of the file that we should write
-         stdout to
-      append: True if we want to append to the file instead of overwriting it
-      std_in: a string that should be written to the process executing to
-         interact with it (if needed)"""
-    if self.verbose:
-      print ' '.join(cmd_list)
-    out = subprocess.PIPE
-    if outfile:
-      mode = 'w'
-      if append:
-        mode = 'a+'
-      out = open(outfile, mode)
-      if append:
-        # Annoying Windows "feature" -- append doesn't actually append unless
-        # you explicitly go to the end of the file.
-        # http://mail.python.org/pipermail/python-list/2009-October/1221859.html
-        out.seek(0, os.SEEK_END)
-    p = subprocess.Popen(cmd_list, stdout = out, stderr=subprocess.PIPE,
-                         stdin=subprocess.PIPE, shell=self.has_shell)
-    output, stderr = p.communicate(std_in)
-    if output:
-      print output
-    if stderr:
-      print stderr
-    return output, stderr
-
-  def RunBrowserPerfRunnerCmd(self, browser, url_path, file_path_to_test_code,
-      trace_file, code_root=''):
-    command_list = [os.path.join(DART_REPO_LOC, utils.GetBuildRoot(
-        utils.GuessOS(), 'release', 'ia32'), 'dart-sdk', 'bin', 'dart'),
-        '--package-root=%s' % os.path.join(file_path_to_test_code, 'packages'),
-        os.path.join(file_path_to_test_code, 'packages',
-        'browser_controller', 'browser_perf_testing.dart'), '--browser',
-        browser, '--test_path=%s' % url_path]
-    if code_root != '':
-      command_list += ['--code_root=%s' % code_root]
-
-    if browser == 'dartium':
-      dartium_path = os.path.join(DART_REPO_LOC, 'client', 'tests', 'dartium')
-      if platform.system() == 'Windows':
-        dartium_path = os.path.join(dartium_path, 'chrome.exe');
-      elif platform.system() == 'Darwin':
-        dartium_path = os.path.join(dartium_path, 'Chromium.app', 'Contents',
-            'MacOS', 'Chromium')
-      else:
-        dartium_path = os.path.join(dartium_path, 'chrome')
-      command_list += ['--executable=%s' % dartium_path]
-
-    self.RunCmd(command_list, trace_file, append=True)
-
-  def TimeCmd(self, cmd):
-    """Determine the amount of (real) time it takes to execute a given
-    command."""
-    start = time.time()
-    self.RunCmd(cmd)
-    return time.time() - start
-
-  def ClearOutUnversionedFiles(self):
-    """Remove all files that are unversioned by svn."""
-    if os.path.exists(DART_REPO_LOC):
-      os.chdir(DART_REPO_LOC)
-      results, _ = self.RunCmd(['svn', 'st'])
-      for line in results.split('\n'):
-        if line.startswith('?'):
-          to_remove = line.split()[1]
-          if os.path.isdir(to_remove):
-            shutil.rmtree(to_remove, onerror=TestRunner._OnRmError)
-          else:
-            os.remove(to_remove)
-        elif any(line.startswith(status) for status in ['A', 'M', 'C', 'D']):
-          self.RunCmd(['svn', 'revert', line.split()[1]])
-
-  def GetArchive(self, archive_name):
-    """Wrapper around the pulling down a specific archive from Google Storage.
-    Adds a specific revision argument as needed.
-    Returns: A tuple of a boolean (True if we successfully downloaded the
-    binary), and the stdout and stderr from running this command."""
-    num_fails = 0
-    while True:
-      cmd = ['python', os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'),
-             archive_name]
-      if int(self.current_revision_num) != -1:
-        cmd += ['-r', str(self.current_revision_num)]
-      stdout, stderr = self.RunCmd(cmd)
-      if 'Please try again later' in stdout and num_fails < 20:
-        time.sleep(100)
-        num_fails += 1
-      else:
-        break
-    return (num_fails < 20, stdout, stderr)
-
-  def _Sync(self, revision_num=None):
-    """Update the repository to the latest or specified revision."""
-    os.chdir(dirname(DART_REPO_LOC))
-    self.ClearOutUnversionedFiles()
-    if not revision_num:
-      self.RunCmd(['gclient', 'sync'])
-    else:
-      self.RunCmd(['gclient', 'sync', '-r', str(revision_num), '-t'])
-
-    shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'internal'),
-                    os.path.join(DART_REPO_LOC, 'internal'))
-    shutil.rmtree(os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'),
-                  onerror=TestRunner._OnRmError)
-    shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'third_party', 'gsutil'),
-                    os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'))
-    shutil.copy(os.path.join(TOP_LEVEL_DIR, 'tools', 'get_archive.py'),
-                    os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'))
-    shutil.copy(
-        os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'run_selenium.py'),
-        os.path.join(DART_REPO_LOC, 'tools', 'testing', 'run_selenium.py'))
-
-  @staticmethod
-  def _OnRmError(func, path, exc_info):
-    """On Windows, the output directory is marked as "Read Only," which causes
-    an error to be thrown when we use shutil.rmtree. This helper function
-    changes the permissions so we can still delete the directory."""
-    if os.path.exists(path):
-      os.chmod(path, stat.S_IWRITE)
-      os.unlink(path)
-
-  def SyncAndBuild(self, suites, revision_num=None):
-    """Make sure we have the latest version of of the repo, and build it. We
-    begin and end standing in DART_REPO_LOC.
-
-    Args:
-      suites: The set of suites that we wish to build.
-
-    Returns:
-      err_code = 1 if there was a problem building."""
-    self._Sync(revision_num)
-    if not revision_num:
-      revision_num = SearchForRevision()
-
-    self.current_revision_num = revision_num
-    success, stdout, stderr = self.GetArchive('sdk')
-    if (not os.path.exists(os.path.join(
-        DART_REPO_LOC, 'tools', 'get_archive.py')) or not success
-        or 'InvalidUriError' in stderr or "Couldn't download" in stdout or
-        'Unable to download' in stdout):
-      # Couldn't find the SDK on Google Storage. Build it locally.
-
-      # TODO(efortuna): Currently always building ia32 architecture because we
-      # don't have test statistics for what's passing on x64. Eliminate arch
-      # specification when we have tests running on x64, too.
-      shutil.rmtree(os.path.join(os.getcwd(),
-                    utils.GetBuildRoot(utils.GuessOS())),
-                    onerror=TestRunner._OnRmError)
-      lines = self.RunCmd(['python', os.path.join('tools', 'build.py'), '-m',
-                            'release', '--arch=ia32', 'create_sdk'])
-
-      for line in lines:
-        if 'BUILD FAILED' in line:
-          # Someone checked in a broken build! Stop trying to make it work
-          # and wait to try again.
-          print 'Broken Build'
-          return 1
-    return 0
-
-  def EnsureOutputDirectory(self, dir_name):
-    """Test that the listed directory name exists, and if not, create one for
-    our output to be placed.
-
-    Args:
-      dir_name: the directory we will create if it does not exist."""
-    dir_path = os.path.join(TOP_LEVEL_DIR, 'tools',
-                            'testing', 'perf_testing', dir_name)
-    if not os.path.exists(dir_path):
-      os.makedirs(dir_path)
-      print 'Creating output directory ', dir_path
-
-  def HasInterestingCode(self, revision_num=None):
-    """Tests if there are any versions of files that might change performance
-    results on the server.
-
-    Returns:
-       (False, None): There is no interesting code to run.
-       (True, revisionNumber): There is interesting code to run at revision
-                              revisionNumber.
-       (True, None): There is interesting code to run by syncing to the
-                     tip-of-tree."""
-    if not os.path.exists(DART_REPO_LOC):
-      self._Sync()
-    os.chdir(DART_REPO_LOC)
-    no_effect = ['dart/client', 'dart/compiler', 'dart/editor',
-                 'dart/lib/html/doc', 'dart/pkg', 'dart/tests', 'dart/samples',
-                 'dart/lib/dartdoc', 'dart/lib/i18n', 'dart/lib/unittest',
-                 'dart/tools/dartc', 'dart/tools/get_archive.py',
-                 'dart/tools/test.py', 'dart/tools/testing',
-                 'dart/tools/utils', 'dart/third_party', 'dart/utils']
-    definitely_yes = ['dart/samples/third_party/dromaeo',
-                      'dart/lib/html/dart2js', 'dart/lib/html/dartium',
-                      'dart/lib/scripts', 'dart/lib/src',
-                      'dart/third_party/WebCore']
-    def GetFileList(revision):
-      """Determine the set of files that were changed for a particular
-      revision."""
-      # TODO(efortuna): This assumes you're using svn. Have a git fallback as
-      # well. Pass 'p' in if we have a new certificate for the svn server, we
-      # want to (p)ermanently accept it.
-      results, _ = self.RunCmd([
-          'svn', 'log', 'http://dart.googlecode.com/svn/branches/bleeding_edge',
-          '-v', '-r', str(revision)], std_in='p\r\n')
-      results = results.split('\n')
-      if len(results) <= 3:
-        return []
-      else:
-        # Trim off the details about revision number and commit message. We're
-        # only interested in the files that are changed.
-        results = results[3:]
-        changed_files = []
-        for result in results:
-          if len(result) <= 1:
-            break
-          tokens = result.split()
-          if len(tokens) > 1:
-            changed_files += [tokens[1].replace('/branches/bleeding_edge/', '')]
-        return changed_files
-
-    def HasPerfAffectingResults(files_list):
-      """Determine if this set of changed files might effect performance
-      tests."""
-      def IsSafeFile(f):
-        if not any(f.startswith(prefix) for prefix in definitely_yes):
-          return any(f.startswith(prefix) for prefix in no_effect)
-        return False
-      return not all(IsSafeFile(f) for f in files_list)
-
-    if revision_num:
-      return (HasPerfAffectingResults(GetFileList(
-          revision_num)), revision_num)
-    else:
-      latest_interesting_server_rev = None
-      while not latest_interesting_server_rev:
-        results, _ = self.RunCmd(['svn', 'st', '-u'], std_in='p\r\n')
-        if len(results.split('\n')) >= 2:
-          latest_interesting_server_rev = int(
-              results.split('\n')[-2].split()[-1])
-      if self.backfill:
-        done_cls = list(UpdateSetOfDoneCls())
-        done_cls.sort()
-        if done_cls:
-          last_done_cl = int(done_cls[-1])
-        else:
-          last_done_cl = EARLIEST_REVISION
-        while latest_interesting_server_rev >= last_done_cl:
-          file_list = GetFileList(latest_interesting_server_rev)
-          if HasPerfAffectingResults(file_list):
-            return (True, latest_interesting_server_rev)
-          else:
-            UpdateSetOfDoneCls(latest_interesting_server_rev)
-          latest_interesting_server_rev -= 1
-      else:
-        last_done_cl = int(SearchForRevision(DART_REPO_LOC)) + 1
-        while last_done_cl <= latest_interesting_server_rev:
-          file_list = GetFileList(last_done_cl)
-          if HasPerfAffectingResults(file_list):
-            return (True, last_done_cl)
-          else:
-            UpdateSetOfDoneCls(last_done_cl)
-          last_done_cl += 1
-      return (False, None)
-
-  def GetOsDirectory(self):
-    """Specifies the name of the directory for the testing build of dart, which
-    has yet a different naming convention from utils.getBuildRoot(...)."""
-    if platform.system() == 'Windows':
-      return 'windows'
-    elif platform.system() == 'Darwin':
-      return 'macos'
-    else:
-      return 'linux'
-
-  def ParseArgs(self):
-    parser = optparse.OptionParser()
-    parser.add_option('--suites', '-s', dest='suites', help='Run the specified '
-                      'comma-separated test suites from set: %s' % \
-                      ','.join(TestBuilder.AvailableSuiteNames()),
-                      action='store', default=None)
-    parser.add_option('--forever', '-f', dest='continuous', help='Run this scri'
-                      'pt forever, always checking for the next svn checkin',
-                      action='store_true', default=False)
-    parser.add_option('--nobuild', '-n', dest='no_build', action='store_true',
-                      help='Do not sync with the repository and do not '
-                      'rebuild.', default=False)
-    parser.add_option('--noupload', '-u', dest='no_upload', action='store_true',
-                      help='Do not post the results of the run.', default=False)
-    parser.add_option('--notest', '-t', dest='no_test', action='store_true',
-                      help='Do not run the tests.', default=False)
-    parser.add_option('--verbose', '-v', dest='verbose',
-                      help='Print extra debug output', action='store_true',
-                      default=False)
-    parser.add_option('--backfill', '-b', dest='backfill',
-                      help='Backfill earlier CLs with additional results when '
-                      'there is idle time.', action='store_true',
-                      default=False)
-
-    args, ignored = parser.parse_args()
-
-    if not args.suites:
-      suites = TestBuilder.AvailableSuiteNames()
-    else:
-      suites = []
-      suitelist = args.suites.split(',')
-      for name in suitelist:
-        if name in TestBuilder.AvailableSuiteNames():
-          suites.append(name)
-        else:
-          print ('Error: Invalid suite %s not in ' % name) + \
-              '%s' % ','.join(TestBuilder.AvailableSuiteNames())
-          sys.exit(1)
-    self.suite_names = suites
-    self.no_build = args.no_build
-    self.no_upload = args.no_upload
-    self.no_test = args.no_test
-    self.verbose = args.verbose
-    self.backfill = args.backfill
-    return args.continuous
-
-  def RunTestSequence(self, revision_num=None, num_reruns=1):
-    """Run the set of commands to (possibly) build, run, and post the results
-    of our tests. Returns 0 on a successful run, 1 if we fail to post results or
-    the run failed, -1 if the build is broken.
-    """
-    suites = []
-    success = True
-    if not self.no_build and self.SyncAndBuild(suites, revision_num) == 1:
-      return -1 # The build is broken.
-
-    if not self.current_revision_num:
-      self.current_revision_num = SearchForRevision(DART_REPO_LOC)
-
-    for name in self.suite_names:
-      for run in range(num_reruns):
-        suites += [TestBuilder.MakeTest(name, self)]
-
-    for test in suites:
-      success = success and test.Run()
-    if success:
-      return 0
-    else:
-      return 1
-
-
-class Test(object):
-  """The base class to provide shared code for different tests we will run and
-  post. At a high level, each test has three visitors (the tester and the
-  file_processor) that perform operations on the test object."""
-
-  def __init__(self, result_folder_name, platform_list, variants,
-               values_list, test_runner, tester, file_processor,
-               extra_metrics=['Geo-Mean']):
-    """Args:
-         result_folder_name: The name of the folder where a tracefile of
-             performance results will be stored.
-         platform_list: A list containing the platform(s) that our data has been
-             run on. (command line, firefox, chrome, etc)
-         variants: A list specifying whether we hold data about Frog
-             generated code, plain JS code, or a combination of both, or
-             Dart depending on the test.
-         values_list: A list containing the type of data we will be graphing
-             (benchmarks, percentage passing, etc).
-         test_runner: Reference to the parent test runner object that notifies a
-             test when to run.
-         tester: The visitor that actually performs the test running mechanics.
-         file_processor: The visitor that processes files in the format
-             appropriate for this test.
-         extra_metrics: A list of any additional measurements we wish to keep
-             track of (such as the geometric mean of a set, the sum, etc)."""
-    self.result_folder_name = result_folder_name
-    # cur_time is used as a timestamp of when this performance test was run.
-    self.cur_time = str(time.mktime(datetime.datetime.now().timetuple()))
-    self.values_list = values_list
-    self.platform_list = platform_list
-    self.test_runner = test_runner
-    self.tester = tester
-    self.file_processor = file_processor
-    self.revision_dict = dict()
-    self.values_dict = dict()
-    self.extra_metrics = extra_metrics
-    # Initialize our values store.
-    for platform in platform_list:
-      self.revision_dict[platform] = dict()
-      self.values_dict[platform] = dict()
-      for f in variants:
-        self.revision_dict[platform][f] = dict()
-        self.values_dict[platform][f] = dict()
-        for val in values_list:
-          self.revision_dict[platform][f][val] = []
-          self.values_dict[platform][f][val] = []
-        for extra_metric in extra_metrics:
-          self.revision_dict[platform][f][extra_metric] = []
-          self.values_dict[platform][f][extra_metric] = []
-
-  def IsValidCombination(self, platform, variant):
-    """Check whether data should be captured for this platform/variant
-    combination.
-    """
-    if variant == 'dart_html' and platform != 'dartium':
-      return False
-    if platform == 'dartium' and (variant == 'js' or variant == 'dart2js_html'):
-      # Testing JavaScript performance on Dartium is a waste of time. Should be
-      # same as Chrome.
-      return False
-    if (platform == 'safari' and variant == 'dart2js' and
-        int(self.test_runner.current_revision_num) < 10193):
-      # In revision 10193 we fixed a bug that allows Safari 6 to run dart2js
-      # code. Since we can't change the Safari version on the machine, we're
-      # just not running
-      # for this case.
-      return False
-    return True
-
-  def Run(self):
-    """Run the benchmarks/tests from the command line and plot the
-    results.
-    """
-    for visitor in [self.tester, self.file_processor]:
-      visitor.Prepare()
-
-    os.chdir(TOP_LEVEL_DIR)
-    self.test_runner.EnsureOutputDirectory(self.result_folder_name)
-    self.test_runner.EnsureOutputDirectory(os.path.join(
-        'old', self.result_folder_name))
-    os.chdir(DART_REPO_LOC)
-    if not self.test_runner.no_test:
-      self.tester.RunTests()
-
-    os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'perf_testing'))
-
-    files = os.listdir(self.result_folder_name)
-    post_success = True
-    for afile in files:
-      if not afile.startswith('.'):
-        should_move_file = self.file_processor.ProcessFile(afile, True)
-        if should_move_file:
-          shutil.move(os.path.join(self.result_folder_name, afile),
-                      os.path.join('old', self.result_folder_name, afile))
-        else:
-          post_success = False
-
-    return post_success
-
-
-class Tester(object):
-  """The base level visitor class that runs tests. It contains convenience
-  methods that many Tester objects use. Any class that would like to be a
-  TesterVisitor must implement the RunTests() method."""
-
-  def __init__(self, test):
-    self.test = test
-
-  def Prepare(self):
-    """Perform any initial setup required before the test is run."""
-    pass
-
-  def AddSvnRevisionToTrace(self, outfile, browser = None):
-    """Add the svn version number to the provided tracefile."""
-    def get_dartium_revision():
-      version_file_name = os.path.join(DART_REPO_LOC, 'client', 'tests',
-                                       'dartium', 'LAST_VERSION')
-      try:
-        version_file = open(version_file_name, 'r')
-        version = version_file.read().split('.')[-3].split('-')[-1]
-        version_file.close()
-        return version
-      except IOError as e:
-        dartium_dir = os.path.join(DART_REPO_LOC, 'client', 'tests', 'dartium')
-        if (os.path.exists(os.path.join(dartium_dir, 'Chromium.app', 'Contents',
-            'MacOS', 'Chromium') or os.path.exists(os.path.join(dartium_dir,
-            'chrome.exe'))) or
-            os.path.exists(os.path.join(dartium_dir, 'chrome'))):
-          print "Error: VERSION file wasn't found."
-          return SearchForRevision()
-        else:
-          raise
-
-    if browser and browser == 'dartium':
-      revision = get_dartium_revision()
-      self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
-    else:
-      revision = SearchForRevision()
-      self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
-
-
-class Processor(object):
-  """The base level vistor class that processes tests. It contains convenience
-  methods that many File Processor objects use. Any class that would like to be
-  a ProcessorVisitor must implement the ProcessFile() method."""
-
-  SCORE = 'Score'
-  COMPILE_TIME = 'CompileTime'
-  CODE_SIZE = 'CodeSize'
-
-  def __init__(self, test):
-    self.test = test
-
-  def Prepare(self):
-    """Perform any initial setup required before the test is run."""
-    pass
-
-  def OpenTraceFile(self, afile, not_yet_uploaded):
-    """Find the correct location for the trace file, and open it.
-    Args:
-      afile: The tracefile name.
-      not_yet_uploaded: True if this file is to be found in a directory that
-         contains un-uploaded data.
-    Returns: A file object corresponding to the given file name."""
-    file_path = os.path.join(self.test.result_folder_name, afile)
-    if not not_yet_uploaded:
-      file_path = os.path.join('old', file_path)
-    return open(file_path)
-
-  def ReportResults(self, benchmark_name, score, platform, variant,
-                     revision_number, metric):
-    """Store the results of the benchmark run.
-    Args:
-      benchmark_name: The name of the individual benchmark.
-      score: The numerical value of this benchmark.
-      platform: The platform the test was run on (firefox, command line, etc).
-      variant: Specifies whether the data was about generated Frog, js, a
-          combination of both, or Dart depending on the test.
-      revision_number: The revision of the code (and sometimes the revision of
-          dartium).
-
-    Returns: True if the post was successful file."""
-    return post_results.report_results(benchmark_name, score, platform, variant,
-                                       revision_number, metric)
-
-  def CalculateGeometricMean(self, platform, variant, svn_revision):
-    """Calculate the aggregate geometric mean for JS and dart2js benchmark sets,
-    given two benchmark dictionaries."""
-    geo_mean = 0
-    if self.test.IsValidCombination(platform, variant):
-      for benchmark in self.test.values_list:
-        if not self.test.values_dict[platform][variant][benchmark]:
-          print 'Error determining mean for %s %s %s' % (platform, variant,
-                                                         benchmark)
-          continue
-        geo_mean += math.log(
-            self.test.values_dict[platform][variant][benchmark][-1])
-
-    self.test.values_dict[platform][variant]['Geo-Mean'] += \
-        [math.pow(math.e, geo_mean / len(self.test.values_list))]
-    self.test.revision_dict[platform][variant]['Geo-Mean'] += [svn_revision]
-
-  def GetScoreType(self, benchmark_name):
-    """Determine the type of score for posting -- default is 'Score' (aka
-    Runtime), other options are CompileTime and CodeSize."""
-    return self.SCORE
-
-
-class RuntimePerformanceTest(Test):
-  """Super class for all runtime performance testing."""
-
-  def __init__(self, result_folder_name, platform_list, platform_type,
-               versions, benchmarks, test_runner, tester, file_processor):
-    """Args:
-        result_folder_name: The name of the folder where a tracefile of
-            performance results will be stored.
-        platform_list: A list containing the platform(s) that our data has been
-            run on. (command line, firefox, chrome, etc)
-        variants: A list specifying whether we hold data about Frog
-            generated code, plain JS code, or a combination of both, or
-            Dart depending on the test.
-        values_list: A list containing the type of data we will be graphing
-            (benchmarks, percentage passing, etc).
-        test_runner: Reference to the parent test runner object that notifies a
-            test when to run.
-        tester: The visitor that actually performs the test running mechanics.
-        file_processor: The visitor that processes files in the format
-            appropriate for this test.
-        extra_metrics: A list of any additional measurements we wish to keep
-            track of (such as the geometric mean of a set, the sum, etc)."""
-    super(RuntimePerformanceTest, self).__init__(result_folder_name,
-          platform_list, versions, benchmarks, test_runner, tester,
-          file_processor)
-    self.platform_list = platform_list
-    self.platform_type = platform_type
-    self.versions = versions
-    self.benchmarks = benchmarks
-
-
-class BrowserTester(Tester):
-  @staticmethod
-  def GetBrowsers(add_dartium=True):
-    browsers = ['ff', 'chrome']
-    if add_dartium:
-      browsers += ['dartium']
-    has_shell = False
-    if platform.system() == 'Darwin':
-      browsers += ['safari']
-    if platform.system() == 'Windows':
-      browsers += ['ie']
-      has_shell = True
-    return browsers
-
-
-class DromaeoTester(Tester):
-  DROMAEO_BENCHMARKS = {
-      'attr': ('attributes', [
-          'getAttribute',
-          'element.property',
-          'setAttribute',
-          'element.property = value']),
-      'modify': ('modify', [
-          'createElement',
-          'createTextNode',
-          'innerHTML',
-          'cloneNode',
-          'appendChild',
-          'insertBefore']),
-      'query': ('query', [
-          'getElementById',
-          'getElementById (not in document)',
-          'getElementsByTagName(div)',
-          'getElementsByTagName(p)',
-          'getElementsByTagName(a)',
-          'getElementsByTagName(*)',
-          'getElementsByTagName (not in document)',
-          'getElementsByName',
-          'getElementsByName (not in document)']),
-      'traverse': ('traverse', [
-          'firstChild',
-          'lastChild',
-          'nextSibling',
-          'previousSibling',
-          'childNodes'])
-  }
-
-  # Use filenames that don't have unusual characters for benchmark names.
-  @staticmethod
-  def LegalizeFilename(str):
-    remap = {
-        ' ': '_',
-        '(': '_',
-        ')': '_',
-        '*': 'ALL',
-        '=': 'ASSIGN',
-        }
-    for (old, new) in remap.iteritems():
-      str = str.replace(old, new)
-    return str
-
-  # TODO(vsm): This is a hack to skip breaking tests.  Triage this
-  # failure properly.  The modify suite fails on 32-bit chrome, which
-  # is the default on mac and win.
-  @staticmethod
-  def GetValidDromaeoTags():
-    tags = [tag for (tag, _) in DromaeoTester.DROMAEO_BENCHMARKS.values()]
-    if platform.system() == 'Darwin' or platform.system() == 'Windows':
-      tags.remove('modify')
-    return tags
-
-  @staticmethod
-  def GetDromaeoBenchmarks():
-    valid = DromaeoTester.GetValidDromaeoTags()
-    benchmarks = reduce(lambda l1,l2: l1+l2,
-                        [tests for (tag, tests) in
-                         DromaeoTester.DROMAEO_BENCHMARKS.values()
-                         if tag in valid])
-    return map(DromaeoTester.LegalizeFilename, benchmarks)
-
-  @staticmethod
-  def GetDromaeoVersions():
-    return ['js', 'dart2js_html', 'dart_html']
-
-
-class DromaeoTest(RuntimePerformanceTest):
-  """Runs Dromaeo tests, in the browser."""
-  def __init__(self, test_runner):
-    super(DromaeoTest, self).__init__(
-        self.Name(),
-        BrowserTester.GetBrowsers(True),
-        'browser',
-        DromaeoTester.GetDromaeoVersions(),
-        DromaeoTester.GetDromaeoBenchmarks(), test_runner,
-        self.DromaeoPerfTester(self),
-        self.DromaeoFileProcessor(self))
-
-  @staticmethod
-  def Name():
-    return 'dromaeo'
-
-  class DromaeoPerfTester(DromaeoTester):
-    def RunTests(self):
-      """Run dromaeo in the browser."""
-      success, _, _ = self.test.test_runner.GetArchive('dartium')
-      if not success:
-        # Unable to download dartium. Try later.
-        return
-
-      # Build tests.
-      current_path = os.getcwd()
-      os.chdir(os.path.join(DART_REPO_LOC, 'samples', 'third_party',
-          'dromaeo'))
-      # Note: This uses debug on purpose, so that we can also run performance
-      # tests on pure Dart applications in Dartium. Pub --debug simply also
-      # moves the .dart files to the build directory. To ensure effective
-      # comparison, though, ensure that minify: true is set in your transformer
-      # compilation step in your pubspec.
-      stdout, _ = self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC,
-          utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
-          'dart-sdk', 'bin', 'pub'), 'build', '--mode=debug'])
-      os.chdir(current_path)
-      if 'failed' in stdout:
-        return
-
-      versions = DromaeoTester.GetDromaeoVersions()
-
-      for browser in BrowserTester.GetBrowsers():
-        for version_name in versions:
-          if not self.test.IsValidCombination(browser, version_name):
-            continue
-          version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery(
-              browser, version_name)
-          self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
-              'tools', 'testing', 'perf_testing', self.test.result_folder_name,
-              'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name))
-          self.AddSvnRevisionToTrace(self.test.trace_file, browser)
-          url_path = '/'.join(['/code_root', 'build', 'web', 'index%s.html?%s'%(
-              '-dart' if version_name == 'dart_html' else '-js',
-              version)])
-
-          self.test.test_runner.RunBrowserPerfRunnerCmd(browser, url_path,
-              os.path.join(DART_REPO_LOC, 'samples', 'third_party', 'dromaeo'),
-              self.test.trace_file)
-
-    @staticmethod
-    def GetDromaeoUrlQuery(browser, version):
-      version = version.replace('_','AND')
-      tags = DromaeoTester.GetValidDromaeoTags()
-      return 'OR'.join([ '%sAND%s' % (version, tag) for tag in tags])
-
-
-  class DromaeoFileProcessor(Processor):
-    def ProcessFile(self, afile, should_post_file):
-      """Comb through the html to find the performance results.
-      Returns: True if we successfully posted our data to storage."""
-      parts = afile.split('-')
-      browser = parts[2]
-      version = parts[3]
-
-      bench_dict = self.test.values_dict[browser][version]
-
-      f = self.OpenTraceFile(afile, should_post_file)
-      lines = f.readlines()
-      i = 0
-      revision_num = 0
-      revision_pattern = r'Revision: (\d+)'
-      suite_pattern = r'<div class="result-item done">(.+?)</ol></div>'
-      result_pattern = r'<b>(.+?)</b>(.+?)<small> runs/s(.+)'
-
-      upload_success = True
-      for line in lines:
-        rev = re.match(revision_pattern, line.strip().replace('"', ''))
-        if rev:
-          revision_num = int(rev.group(1))
-          continue
-
-        suite_results = re.findall(suite_pattern, line)
-        if suite_results:
-          for suite_result in suite_results:
-            results = re.findall(r'<li>(.*?)</li>', suite_result)
-            if results:
-              for result in results:
-                r = re.match(result_pattern, result)
-                name = DromaeoTester.LegalizeFilename(r.group(1).strip(':'))
-                score = float(r.group(2))
-                bench_dict[name] += [float(score)]
-                self.test.revision_dict[browser][version][name] += \
-                    [revision_num]
-                if not self.test.test_runner.no_upload and should_post_file:
-                  upload_success = upload_success and self.ReportResults(
-                      name, score, browser, version, revision_num,
-                      self.GetScoreType(name))
-                else:
-                  upload_success = False
-
-      f.close()
-      self.CalculateGeometricMean(browser, version, revision_num)
-      return upload_success
-
-class TodoMVCTester(BrowserTester):
-    @staticmethod
-    def GetVersions():
-      return ['js', 'dart2js_html', 'dart_html']
-
-    @staticmethod
-    def GetBenchmarks():
-      return ['TodoMVCstartup']
-
-class TodoMVCStartupTest(RuntimePerformanceTest):
-  """Start up TodoMVC and see how long it takes to start."""
-  def __init__(self, test_runner):
-    super(TodoMVCStartupTest, self).__init__(
-        self.Name(),
-        BrowserTester.GetBrowsers(True),
-        'browser',
-        TodoMVCTester.GetVersions(),
-        TodoMVCTester.GetBenchmarks(), test_runner,
-        self.TodoMVCStartupTester(self),
-        self.TodoMVCFileProcessor(self))
-
-  @staticmethod
-  def Name():
-    return 'todoMvcStartup'
-
-  class TodoMVCStartupTester(BrowserTester):
-    def RunTests(self):
-      """Run dromaeo in the browser."""
-      success, _, _ = self.test.test_runner.GetArchive('dartium')
-      if not success:
-        # Unable to download dartium. Try later.
-        return
-
-      dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo')
-      current_path = os.getcwd()
-
-      os.chdir(os.path.join(DART_REPO_LOC, 'samples', 'third_party',
-          'todomvc_performance'))
-      self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC,
-          utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
-          'dart-sdk', 'bin', 'pub'), 'build', '--mode=debug'])
-      os.chdir('js_todomvc');
-      self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC,
-          utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
-          'dart-sdk', 'bin', 'pub'), 'get'])
-
-      versions = TodoMVCTester.GetVersions()
-
-      for browser in BrowserTester.GetBrowsers():
-        for version_name in versions:
-          if not self.test.IsValidCombination(browser, version_name):
-            continue
-          self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
-              'tools', 'testing', 'perf_testing', self.test.result_folder_name,
-              'todoMvcStartup-%s-%s-%s' % (self.test.cur_time, browser,
-              version_name))
-          self.AddSvnRevisionToTrace(self.test.trace_file, browser)
-
-          if version_name == 'js':
-            code_root = os.path.join(DART_REPO_LOC, 'samples', 'third_party',
-                'todomvc_performance', 'js_todomvc')
-            self.test.test_runner.RunBrowserPerfRunnerCmd(browser,
-                '/code_root/index.html', code_root, self.test.trace_file,
-                code_root)
-          else:
-            self.test.test_runner.RunBrowserPerfRunnerCmd(browser,
-                '/code_root/build/web/startup-performance.html', os.path.join(
-                DART_REPO_LOC, 'samples', 'third_party', 'todomvc_performance'),
-                self.test.trace_file)
-
-  class TodoMVCFileProcessor(Processor):
-    def ProcessFile(self, afile, should_post_file):
-      """Comb through the html to find the performance results.
-      Returns: True if we successfully posted our data to storage."""
-      parts = afile.split('-')
-      browser = parts[2]
-      version = parts[3]
-
-      bench_dict = self.test.values_dict[browser][version]
-
-      f = self.OpenTraceFile(afile, should_post_file)
-      lines = f.readlines()
-      i = 0
-      revision_num = 0
-      revision_pattern = r'Revision: (\d+)'
-      result_pattern = r'The startup time is (\d+)'
-
-      upload_success = True
-      for line in lines:
-        rev = re.match(revision_pattern, line.strip().replace('"', ''))
-        if rev:
-          revision_num = int(rev.group(1))
-          continue
-
-        results = re.search(result_pattern, line)
-        if results:
-          score = float(results.group(1))
-          name = TodoMVCTester.GetBenchmarks()[0]
-          bench_dict[name] += [float(score)]
-          self.test.revision_dict[browser][version][name] += \
-              [revision_num]
-          if not self.test.test_runner.no_upload and should_post_file:
-            upload_success = upload_success and self.ReportResults(
-                name, score, browser, version, revision_num,
-                self.GetScoreType(name))
-
-      f.close()
-      self.CalculateGeometricMean(browser, version, revision_num)
-      return upload_success
-
-
-class TestBuilder(object):
-  """Construct the desired test object."""
-  available_suites = dict((suite.Name(), suite) for suite in [
-      DromaeoTest, TodoMVCStartupTest])
-
-  @staticmethod
-  def MakeTest(test_name, test_runner):
-    return TestBuilder.available_suites[test_name](test_runner)
-
-  @staticmethod
-  def AvailableSuiteNames():
-    return TestBuilder.available_suites.keys()
-
-
-def SearchForRevision(directory = None):
-  """Find the current revision number in the desired directory. If directory is
-  None, find the revision number in the current directory."""
-  def FindRevision(svn_info_command):
-    p = subprocess.Popen(svn_info_command, stdout = subprocess.PIPE,
-                         stderr = subprocess.STDOUT,
-                         shell = (platform.system() == 'Windows'))
-    output, _ = p.communicate()
-    for line in output.split('\n'):
-      if 'Revision' in line:
-        return int(line.split()[1])
-    return -1
-
-  cwd = os.getcwd()
-  if not directory:
-    directory = cwd
-  os.chdir(directory)
-  revision_num = int(FindRevision(['svn', 'info']))
-  if revision_num == -1:
-    revision_num = int(FindRevision(['git', 'svn', 'info']))
-  os.chdir(cwd)
-  return str(revision_num)
-
-
-def UpdateSetOfDoneCls(revision_num=None):
-  """Update the set of CLs that do not need additional performance runs.
-  Args:
-  revision_num: an additional number to be added to the 'done set'
-  """
-  filename = os.path.join(TOP_LEVEL_DIR, 'cached_results.txt')
-  if not os.path.exists(filename):
-    f = open(filename, 'w')
-    results = set()
-    pickle.dump(results, f)
-    f.close()
-  f = open(filename, 'r+')
-  result_set = pickle.load(f)
-  if revision_num:
-    f.seek(0)
-    result_set.add(revision_num)
-    pickle.dump(result_set, f)
-  f.close()
-  return result_set
-
-
-def FillInBackHistory(results_set, runner):
-  """Fill in back history performance data. This is done one of two ways, with
-  equal probability of trying each way (falling back on the sequential version
-  as our data becomes more densely populated)."""
-  revision_num = int(SearchForRevision(DART_REPO_LOC))
-  has_run_extra = False
-
-  def TryToRunAdditional(revision_number):
-    """Determine the number of results we have stored for a particular revision
-    number, and if it is less than 10, run some extra tests.
-    Args:
-      - revision_number: the revision whose performance we want to potentially
-        test.
-    Returns: True if we successfully ran some additional tests."""
-    if not runner.HasInterestingCode(revision_number)[0]:
-      results_set = UpdateSetOfDoneCls(revision_number)
-      return False
-    a_test = TestBuilder.MakeTest(runner.suite_names[0], runner)
-    benchmark_name = a_test.values_list[0]
-    platform_name = a_test.platform_list[0]
-    variant = a_test.values_dict[platform_name].keys()[0]
-    num_results = post_results.get_num_results(benchmark_name,
-        platform_name, variant, revision_number,
-        a_test.file_processor.GetScoreType(benchmark_name))
-    if num_results < 10:
-      # Run at most two more times.
-      if num_results > 8:
-        reruns = 10 - num_results
-      else:
-        reruns = 2
-      run = runner.RunTestSequence(revision_num=str(revision_number),
-          num_reruns=reruns)
-    if num_results >= 10 or run == 0 and num_results + reruns >= 10:
-      results_set = UpdateSetOfDoneCls(revision_number)
-    elif run != 0:
-      return False
-    return True
-
-  # Try to get up to 10 runs of each CL, starting with the most recent
-  # CL that does not yet have 10 runs. But only perform a set of extra
-  # runs at most 2 at a time before checking to see if new code has been
-  # checked in.
-  while revision_num > EARLIEST_REVISION and not has_run_extra:
-    if revision_num not in results_set:
-      has_run_extra = TryToRunAdditional(revision_num)
-    revision_num -= 1
-  if not has_run_extra:
-    # No more extra back-runs to do (for now). Wait for new code.
-    time.sleep(200)
-  return results_set
-
-
-def main():
-  runner = TestRunner()
-  continuous = runner.ParseArgs()
-
-  if not os.path.exists(DART_REPO_LOC):
-    os.mkdir(dirname(DART_REPO_LOC))
-    os.chdir(dirname(DART_REPO_LOC))
-    p = subprocess.Popen('gclient config https://dart.googlecode.com/svn/' +
-                         'branches/bleeding_edge/deps/all.deps',
-                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                         shell=True)
-    p.communicate()
-  if continuous:
-    while True:
-      results_set = UpdateSetOfDoneCls()
-      (is_interesting, interesting_rev_num) = runner.HasInterestingCode()
-      if is_interesting:
-        runner.RunTestSequence(interesting_rev_num)
-      else:
-        if runner.backfill:
-          results_set = FillInBackHistory(results_set, runner)
-        else:
-          time.sleep(200)
-  else:
-    runner.RunTestSequence()
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/testing/run_selenium.py b/tools/testing/run_selenium.py
index ba4cc6d..e270619 100755
--- a/tools/testing/run_selenium.py
+++ b/tools/testing/run_selenium.py
@@ -60,16 +60,10 @@
   source = source[index + len(string):end_index]
   return 'Score:' in source
 
-def dromaeo_test_done(source):
-  """Tests to see if our performance test is done by printing a score."""
-  #TODO(efortuna): Access these elements in a nicer way using DOM parser.
-  return '<body class="alldone">' in source
-
 # TODO(vsm): Ideally, this wouldn't live in this file.
 CONFIGURATIONS = {
     'correctness': correctness_test_done,
-    'perf': perf_test_done,
-    'dromaeo': dromaeo_test_done
+    'perf': perf_test_done
 }
 
 def run_test_in_browser(browser, html_out, timeout, mode, refresh):
@@ -247,7 +241,6 @@
   browser.quit()
 
 def report_results(mode, source, browser):
-  # TODO(vsm): Add a failure check for Dromaeo.
   if mode != 'correctness':
     # We're running a performance test.
     print source.encode('utf8')
diff --git a/tools/utils.py b/tools/utils.py
index efcb886..aaef94c 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -626,6 +626,8 @@
       name = 'dart-mips'
     elif arch == 'arm':
       name = 'dart-arm'
+    elif arch == 'arm64':
+      name = 'dart-arm'
   return os.path.join(CheckedInSdkPath(), 'bin', name)