Version 0.7.4.0 .

svn merge -r 27471:27585 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@27587 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
index be0a360..befb1a9 100644
--- a/pkg/custom_element/lib/custom-elements.debug.js
+++ b/pkg/custom_element/lib/custom-elements.debug.js
@@ -131,8 +131,7 @@
 } else {
   (function() {
     var defineProperty = Object.defineProperty;
-    var hasOwnProperty = Object.hasOwnProperty;
-    var counter = new Date().getTime() % 1e9;
+    var counter = Date.now() % 1e9;
 
     SideTable = function() {
       this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
@@ -140,10 +139,16 @@
 
     SideTable.prototype = {
       set: function(key, value) {
-        defineProperty(key, this.name, {value: value, writable: true});
+        var entry = key[this.name];
+        if (entry && entry[0] === key)
+          entry[1] = value;
+        else
+          defineProperty(key, this.name, {value: [key, value], writable: true});
       },
       get: function(key) {
-        return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined;
+        var entry;
+        return (entry = key[this.name]) && entry[0] === key ?
+            entry[1] : undefined;
       },
       delete: function(key) {
         this.set(key, undefined);
@@ -700,15 +705,7 @@
 
 (function(scope){
 
-/*
-if (HTMLElement.prototype.webkitShadowRoot) {
-  Object.defineProperty(HTMLElement.prototype, 'shadowRoot', {
-    get: function() {
-      return this.webkitShadowRoot;
-    }
-  };
-}
-*/
+var logFlags = window.logFlags || {};
 
 // walk the subtree rooted at node, applying 'find(element, data)' function
 // to each element
@@ -812,7 +809,7 @@
   // TODO(sjmiles): when logging, do work on all custom elements so we can
   // track behavior even when callbacks not defined
   //console.log('inserted: ', element.localName);
-  if (element.enteredDocumentCallback || (element.__upgraded__ && logFlags.dom)) {
+  if (element.enteredViewCallback || (element.__upgraded__ && logFlags.dom)) {
     logFlags.dom && console.group('inserted:', element.localName);
     if (inDocument(element)) {
       element.__inserted = (element.__inserted || 0) + 1;
@@ -824,9 +821,9 @@
       if (element.__inserted > 1) {
         logFlags.dom && console.warn('inserted:', element.localName,
           'insert/remove count:', element.__inserted)
-      } else if (element.enteredDocumentCallback) {
+      } else if (element.enteredViewCallback) {
         logFlags.dom && console.log('inserted:', element.localName);
-        element.enteredDocumentCallback();
+        element.enteredViewCallback();
       }
     }
     logFlags.dom && console.groupEnd();
@@ -843,7 +840,7 @@
 function removed(element) {
   // TODO(sjmiles): temporary: do work on all custom elements so we can track
   // behavior even when callbacks not defined
-  if (element.leftDocumentCallback || (element.__upgraded__ && logFlags.dom)) {
+  if (element.leftViewCallback || (element.__upgraded__ && logFlags.dom)) {
     logFlags.dom && console.log('removed:', element.localName);
     if (!inDocument(element)) {
       element.__inserted = (element.__inserted || 0) - 1;
@@ -855,8 +852,8 @@
       if (element.__inserted < 0) {
         logFlags.dom && console.warn('removed:', element.localName,
             'insert/remove count:', element.__inserted)
-      } else if (element.leftDocumentCallback) {
-        element.leftDocumentCallback();
+      } else if (element.leftViewCallback) {
+        element.leftViewCallback();
       }
     }
   }
@@ -864,8 +861,10 @@
 
 function inDocument(element) {
   var p = element;
+  var doc = window.ShadowDOMPolyfill &&
+      window.ShadowDOMPolyfill.wrapIfNeeded(document) || document;
   while (p) {
-    if (p == element.ownerDocument) {
+    if (p == doc) {
       return true;
     }
     p = p.parentNode || p.host;
@@ -891,13 +890,6 @@
   }
 }
 
-function watchAllShadows(node) {
-  watchShadow(node);
-  forSubtree(node, function(e) {
-    watchShadow(node);
-  });
-}
-
 function filter(inNode) {
   switch (inNode.localName) {
     case 'style':
@@ -933,11 +925,6 @@
         if (filter(n)) {
           return;
         }
-        // watch shadow-roots on nodes that have had them attached manually
-        // TODO(sjmiles): remove if createShadowRoot is overridden
-        // TODO(sjmiles): removed as an optimization, manual shadow roots
-        // must be watched explicitly
-        //watchAllShadows(n);
         // nodes added may need lifecycle management
         addedNode(n);
       });
@@ -981,8 +968,6 @@
 // exports
 
 scope.watchShadow = watchShadow;
-scope.watchAllShadows = watchAllShadows;
-
 scope.upgradeAll = addedNode;
 scope.upgradeSubtree = addedSubtree;
 
@@ -1014,14 +999,11 @@
 
 // native document.register?
 
-var hasNative = Boolean(document.webkitRegister || document.register);
+var hasNative = Boolean(document.register);
 var useNative = !flags.register && hasNative;
 
 if (useNative) {
 
-  // normalize
-  document.register = document.register || document.webkitRegister;
-
   // stub
   var nop = function() {};
 
@@ -1030,7 +1012,6 @@
   scope.upgradeElement = nop;
 
   scope.watchShadow = nop;
-  scope.watchAllShadows = nop;
   scope.upgrade = nop;
   scope.upgradeAll = nop;
   scope.upgradeSubtree = nop;
@@ -1091,7 +1072,7 @@
     if (name.indexOf('-') < 0) {
       // TODO(sjmiles): replace with more appropriate error (EricB can probably
       // offer guidance)
-      throw new Error('document.register: first argument `name` must contain a dash (\'-\'). Argument was \'' + String(name) + '\'.');
+      throw new Error('document.register: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
     }
     // record name
     definition.name = name;
@@ -1162,11 +1143,11 @@
     // prototype for precise mixing in
     if (!Object.__proto__) {
       // default prototype
-      var native = HTMLElement.prototype;
+      var nativePrototype = HTMLElement.prototype;
       // work out prototype when using type-extension
       if (definition.is) {
         var inst = document.createElement(definition.tag);
-        native = Object.getPrototypeOf(inst);
+        nativePrototype = Object.getPrototypeOf(inst);
       }
       // ensure __proto__ reference is installed at each point on the prototype
       // chain.
@@ -1174,14 +1155,14 @@
       // of prototype swizzling. In this case, this generated __proto__ provides
       // limited support for prototype traversal.
       var proto = definition.prototype, ancestor;
-      while (proto && (proto !== native)) {
+      while (proto && (proto !== nativePrototype)) {
         var ancestor = Object.getPrototypeOf(proto);
         proto.__proto__ = ancestor;
         proto = ancestor;
       }
     }
     // cache this in case of mixin
-    definition.native = native;
+    definition.native = nativePrototype;
   }
 
   // SECTION 4
@@ -1289,7 +1270,7 @@
 
   function registerDefinition(name, definition) {
     if (registry[name]) {
-      throw new Error('a type with that name is already registered.');
+      throw new Error('Cannot register a tag more than once');
     }
     registry[name] = definition;
   }
@@ -1442,14 +1423,16 @@
 (function(){
 
 // bootstrap parsing
-
 function bootstrap() {
-  // go async so call stack can unwind
-  setTimeout(function() {
-    // parse document
-    CustomElements.parser.parse(document);
-    // one more pass before register is 'live'
-    CustomElements.upgradeDocument(document);
+  // parse document
+  CustomElements.parser.parse(document);
+  // one more pass before register is 'live'
+  CustomElements.upgradeDocument(document);
+  // choose async
+  var async = window.Platform && Platform.endOfMicrotask ?
+    Platform.endOfMicrotask :
+    setTimeout;
+  async(function() {
     // set internal 'ready' flag, now document.register will trigger
     // synchronous upgrades
     CustomElements.ready = true;
@@ -1462,7 +1445,7 @@
     document.body.dispatchEvent(
       new CustomEvent('WebComponentsReady', {bubbles: true})
     );
-  }, 0);
+  });
 }
 
 // CustomEvent shim for IE
diff --git a/pkg/custom_element/lib/custom-elements.min.js b/pkg/custom_element/lib/custom-elements.min.js
index 7f7c6e3..3207b81 100644
--- a/pkg/custom_element/lib/custom-elements.min.js
+++ b/pkg/custom_element/lib/custom-elements.min.js
@@ -25,4 +25,4 @@
 // 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.
-window.CustomElements={flags:{}};var SideTable;if("undefined"!=typeof WeakMap&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:function(){var a=Object.defineProperty,b=Object.hasOwnProperty,c=(new Date).getTime()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(c++ +"__")},SideTable.prototype={set:function(b,c){a(b,this.name,{value:c,writable:!0})},get:function(a){return b.call(a,this.name)?a[this.name]:void 0},"delete":function(a){this.set(a,void 0)}}}(),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 SideTable,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 c[d-1]=f,void 0}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}(this),!window.MutationObserver&&(window.MutationObserver=window.WebKitMutationObserver||window.JsMutationObserver,!MutationObserver))throw new Error("no mutation observer support");!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.webkitShadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:(c(a,d),void 0)}),c(a,d)}function e(a){return h(a)?(i(a),!0):(j(a),void 0)}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 logFlags.dom&&console.group("upgrade:",b.localName),a.upgrade(b),logFlags.dom&&console.groupEnd(),!0}}function i(a){j(a),m(a)&&d(a,function(a){j(a)})}function j(a){(a.enteredDocumentCallback||a.__upgraded__&&logFlags.dom)&&(logFlags.dom&&console.group("inserted:",a.localName),m(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?logFlags.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredDocumentCallback&&(logFlags.dom&&console.log("inserted:",a.localName),a.enteredDocumentCallback())),logFlags.dom&&console.groupEnd())}function k(a){l(a),d(a,function(a){l(a)})}function l(a){(a.leftDocumentCallback||a.__upgraded__&&logFlags.dom)&&(logFlags.dom&&console.log("removed:",a.localName),m(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?logFlags.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftDocumentCallback&&a.leftDocumentCallback()))}function m(a){for(var b=a;b;){if(b==a.ownerDocument)return!0;b=b.parentNode||b.host}}function n(a){if(a.webkitShadowRoot&&!a.webkitShadowRoot.__watched){logFlags.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.webkitShadowRoot;b;)o(b),b=b.olderShadowRoot}}function o(a){a.__watched||(t(a),a.__watched=!0)}function p(a){n(a),d(a,function(){n(a)})}function q(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function r(a){if(logFlags.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&&(x(a.addedNodes,function(a){q(a)||g(a)}),x(a.removedNodes,function(a){q(a)||k(a)}))}),logFlags.dom&&console.groupEnd()}function s(){r(w.takeRecords())}function t(a){w.observe(a,{childList:!0,subtree:!0})}function u(a){t(a)}function v(a){logFlags.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),logFlags.dom&&console.groupEnd()}var w=new MutationObserver(r),x=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=n,a.watchAllShadows=p,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=u,a.upgradeDocument=v,a.takeRecords=s}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.register: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.register: first argument `name` must contain a dash ('-'). Argument was '"+String(b)+"'.");if(g.name=b,!g.prototype)throw new Error("Options missing required prototype property");return g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),m(b,g),g.ctor=n(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeAll(document),g.ctor}function c(a){var b=v[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(w(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),h(b,c),b.__upgraded__=!0,a.upgradeSubtree(b),j(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!==HTMLUnknownElement.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){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a,b){l.call(this,a,b,c)}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments),this.attributeChangedCallback&&this.getAttribute(a)!==d&&this.attributeChangedCallback(a,d)}function m(a,b){if(v[a])throw new Error("a type with that name is already registered.");v[a]=b}function n(a){return function(){return f(a)}}function o(a,b){var c=v[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=o(a);return d.setAttribute("is",b),d}var d=w(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=v[b||a.localName];if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return g(a,c)}}}function q(b){var c=x.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var r=a.flags,s=Boolean(document.webkitRegister||document.register),t=!r.register&&s;if(t){document.register=document.register||document.webkitRegister;var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=u,a.watchAllShadows=u,a.upgrade=u,a.upgradeAll=u,a.upgradeSubtree=u,a.observeDocument=u,a.upgradeDocument=u,a.takeRecords=u}else{var v={},w=document.createElement.bind(document),x=Node.prototype.cloneNode;document.register=b,document.createElement=o,Node.prototype.cloneNode=q,a.registry=v,a.upgrade=p}a.hasNative=s,a.useNative=t}(window.CustomElements),function(){function a(a){return"link"===a.localName&&a.getAttribute("rel")===b}var b=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",c={selectors:["link[rel="+b+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(c.selectors);d(b,function(a){c[c.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(b){a(b)&&this.parseImport(b)},parseImport:function(a){a.content&&c.parse(a.content)}},d=Array.prototype.forEach.call.bind(Array.prototype.forEach);CustomElements.parser=c}(),function(){function a(){setTimeout(function(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document),CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))},0)}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();else{var b=window.HTMLImports?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(b,a)}}();
+window.CustomElements={flags:{}};var SideTable;if("undefined"!=typeof WeakMap&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:function(){var a=Object.defineProperty,b=Date.now()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")},SideTable.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)}}}(),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 SideTable,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 c[d-1]=f,void 0}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}(this),!window.MutationObserver&&(window.MutationObserver=window.WebKitMutationObserver||window.JsMutationObserver,!MutationObserver))throw new Error("no mutation observer support");!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.webkitShadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:(c(a,d),void 0)}),c(a,d)}function e(a){return h(a)?(i(a),!0):(j(a),void 0)}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 v.dom&&console.group("upgrade:",b.localName),a.upgrade(b),v.dom&&console.groupEnd(),!0}}function i(a){j(a),m(a)&&d(a,function(a){j(a)})}function j(a){(a.enteredViewCallback||a.__upgraded__&&v.dom)&&(v.dom&&console.group("inserted:",a.localName),m(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?v.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredViewCallback&&(v.dom&&console.log("inserted:",a.localName),a.enteredViewCallback())),v.dom&&console.groupEnd())}function k(a){l(a),d(a,function(a){l(a)})}function l(a){(a.leftViewCallback||a.__upgraded__&&v.dom)&&(v.dom&&console.log("removed:",a.localName),m(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?v.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftViewCallback&&a.leftViewCallback()))}function m(a){for(var b=a,c=window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(document)||document;b;){if(b==c)return!0;b=b.parentNode||b.host}}function n(a){if(a.webkitShadowRoot&&!a.webkitShadowRoot.__watched){v.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.webkitShadowRoot;b;)o(b),b=b.olderShadowRoot}}function o(a){a.__watched||(s(a),a.__watched=!0)}function p(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function q(a){if(v.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&&(x(a.addedNodes,function(a){p(a)||g(a)}),x(a.removedNodes,function(a){p(a)||k(a)}))}),v.dom&&console.groupEnd()}function r(){q(w.takeRecords())}function s(a){w.observe(a,{childList:!0,subtree:!0})}function t(a){s(a)}function u(a){v.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),v.dom&&console.groupEnd()}var v=window.logFlags||{},w=new MutationObserver(q),x=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=n,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=t,a.upgradeDocument=u,a.takeRecords=r}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.register: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.register: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");if(g.name=b,!g.prototype)throw new Error("Options missing required prototype property");return g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),m(b,g),g.ctor=n(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeAll(document),g.ctor}function c(a){var b=v[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(w(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),h(b,c),b.__upgraded__=!0,a.upgradeSubtree(b),j(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!==HTMLUnknownElement.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){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a,b){l.call(this,a,b,c)}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments),this.attributeChangedCallback&&this.getAttribute(a)!==d&&this.attributeChangedCallback(a,d)}function m(a,b){if(v[a])throw new Error("Cannot register a tag more than once");v[a]=b}function n(a){return function(){return f(a)}}function o(a,b){var c=v[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=o(a);return d.setAttribute("is",b),d}var d=w(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=v[b||a.localName];if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return g(a,c)}}}function q(b){var c=x.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var r=a.flags,s=Boolean(document.register),t=!r.register&&s;if(t){var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=u,a.upgrade=u,a.upgradeAll=u,a.upgradeSubtree=u,a.observeDocument=u,a.upgradeDocument=u,a.takeRecords=u}else{var v={},w=document.createElement.bind(document),x=Node.prototype.cloneNode;document.register=b,document.createElement=o,Node.prototype.cloneNode=q,a.registry=v,a.upgrade=p}a.hasNative=s,a.useNative=t}(window.CustomElements),function(){function a(a){return"link"===a.localName&&a.getAttribute("rel")===b}var b=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",c={selectors:["link[rel="+b+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(c.selectors);d(b,function(a){c[c.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(b){a(b)&&this.parseImport(b)},parseImport:function(a){a.content&&c.parse(a.content)}},d=Array.prototype.forEach.call.bind(Array.prototype.forEach);CustomElements.parser=c}(),function(){function a(){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.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}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();else{var b=window.HTMLImports?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(b,a)}}();
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index 2a13fda..d3bf02f 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -3,10 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * Custom Elements let authors define their own elements. Authors associate code
- * with custom tag names, and then use those custom tag names as they would any
- * standard tag. See <www.polymer-project.org/platform/custom-elements.html>
- * for more information.
+ * Custom DOM elements.
+ *
+ * This library provides access to the Polymer project's
+ * [Custom Elements]
+ * (http://www.polymer-project.org/platform/custom-elements.html)
+ * API, which lets you define your own elements. With custom elements, you
+ * associate code with custom tag names, and then use those custom tag names
+ * as you would any standard tag. For more information, see the
+ * [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/) and its
+ * [custom element example]
+ * (https://www.dartlang.org/polymer-dart/#custom-elements).
  */
 library custom_element;
 
diff --git a/pkg/mdv/lib/mdv.dart b/pkg/mdv/lib/mdv.dart
index ee27616..6e90a77 100644
--- a/pkg/mdv/lib/mdv.dart
+++ b/pkg/mdv/lib/mdv.dart
@@ -4,8 +4,13 @@
 
 // TODO(jmesserly): more commentary here.
 /**
- * This library provides access to Model-Driven-Views APIs on HTML elements.
- * More information can be found at: <https://github.com/Polymer/mdv>.
+ * Template and node binding for HTML elements.
+ *
+ * This library provides access to the Polymer project's
+ * [Template Binding](http://www.polymer-project.org/platform/template.html) and
+ * [Node.bind()](http://www.polymer-project.org/platform/node_bind.html) APIs.
+ * Find more information at the
+ * [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/).
  */
 library mdv;
 
diff --git a/pkg/observe/lib/observe.dart b/pkg/observe/lib/observe.dart
index 8b972d3..2bb1200 100644
--- a/pkg/observe/lib/observe.dart
+++ b/pkg/observe/lib/observe.dart
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * *Warning*: this library is experimental, and APIs are subject to change.
+ * Support for observing changes in model-view architectures.
+ *
+ * **Warning:** This library is experimental, and APIs are subject to change.
  *
  * This library is used to observe changes to [Observable] types. It also
  * has helpers to make implementing and using [Observable] objects easy.
diff --git a/pkg/pkg.status b/pkg/pkg.status
index e398666..f5a12e1 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -65,6 +65,9 @@
 polymer/test/events_test: Fail # Issue 12865, 13197
 polymer/test/event_path_test: Fail # Issue 12865, 13197
 
+[ $runtime == safari || $runtime == ie9 ]
+polymer_expressions/test/syntax_test: Fail # Issue 13361
+
 [ $runtime == ff ]
 polymer/test/event_path_test: Fail # Issue 12865, 13197
 
diff --git a/pkg/polymer/README.md b/pkg/polymer/README.md
index d4d177f0b..3ab84b8 100644
--- a/pkg/polymer/README.md
+++ b/pkg/polymer/README.md
@@ -1,15 +1,38 @@
 Polymer.dart
 ============
 
-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.dart is a set of comprehensive UI and utility components
+for building web applications.
+With Polymer.dart's custom elements, templating, data binding,
+and other features,
+you can quickly build structured, encapsulated, client-side web apps.
 
-Polymer.dart is a Dart port of Polymer created and maintained by the Dart team.
+Polymer.dart is a Dart port of
+[Polymer][polymer] created and maintained by the Dart team.
 The Dart team is collaborating with the Polymer team to ensure that polymer.dart
 elements and polyfills are fully compatible with Polymer.
 
-For more information about Polymer, see <http://www.polymer-project.org/>.
-For more information about Dart, see <http://www.dartlang.org/>.
+Polymer.dart replaces Web UI, which has been deprecated.
+
+
+Learn More
+----------
+
+* The [Polymer.dart][home_page] homepage
+contains a list of features, project status,
+installation instructions, tips for upgrading from Web UI,
+and links to other documentation.
+
+* See our [TodoMVC][] example by opening up the Dart Editor's Welcome Page and
+selecting "TodoMVC".
+
+* For more information about Dart, see <http://www.dartlang.org/>.
+
+* When you use this package,
+you automatically get the
+[polymer_expressions][] package,
+which provides an expressive syntax for use with templates.
+
 
 Try It Now
 -----------
@@ -26,23 +49,10 @@
 <https://pub.dartlang.org/packages/polymer>.
 
 
-Learn More
-----------
-
-**Note**: these documents are currently out of date.
-
-* [Read an overview][overview]
-* [Setup your tools][tools]
-* [Browse the features][features]
-* [Dive into the specification][spec]
-
-See our [TodoMVC][] example by opening up the Dart Editor's Welcome Page and
-selecting "TodoMVC".
-
 Running Tests
 -------------
 
-Dependencies are installed using the [Pub Package Manager][pub].
+Install dependencies using the [Pub Package Manager][pub].
 ```bash
 pub install
 
@@ -51,7 +61,7 @@
 # for links to download `content_shell`)
 test/run.sh
 ```
-Note: to run browser tests you will need to have [content_shell][cs],
+Note: To run browser tests you will need to have [content_shell][cs],
 which can be downloaded prebuilt for [Ubuntu Lucid][cs_lucid],
 [Windows][cs_win], or [Mac][cs_mac]. You can also build it from the
 [Dartium and content_shell sources][dartium_src].
@@ -83,3 +93,6 @@
 [tools]: https://www.dartlang.org/articles/dart-web-components/tools.html
 [spec]: https://www.dartlang.org/articles/dart-web-components/spec.html
 [features]: https://www.dartlang.org/articles/dart-web-components/summary.html
+[home_page]: https://www.dartlang.org/polymer-dart/
+[polymer_expressions]: http://pub.dartlang.org/packages/polymer_expressions/
+[polymer]: http://www.polymer-project.org/
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
index 2e4dd0e..e417fe5 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -3,11 +3,39 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * This library exports all of the commonly used functions and types for
- * building UI's.
+ * Custom HTML tags, data binding, and templates for building
+ * structured, encapsulated, client-side web apps.
  *
- * See this article for more information:
- * <http://www.dartlang.org/articles/dart-web-components/>.
+ * Polymer.dart, the next evolution of Web UI,
+ * is an in-progress Dart port of the
+ * [Polymer project](http://www.polymer-project.org/).
+ * Polymer.dart compiles to JavaScript and runs across the modern web.
+ *
+ * To use polymer.dart in your application,
+ * first add a
+ * [dependency](http://pub.dartlang.org/doc/dependencies.html)
+ * to the app's pubspec.yaml file.
+ * Instead of using the open-ended `any` version specifier,
+ * we recommend using a range of version numbers, as in this example:
+ *
+ *     dependencies:
+ *       polymer: '>=0.7.1 <0.8'
+ *
+ * Then import the library into your application:
+ *
+ *     import 'package:polymer/polymer.dart';
+ *
+ * ## Other resources
+ *
+ * * [Polymer.dart homepage](http://www.dartlang.org/polymer-dart/):
+ * Example code, project status, and
+ * information about how to get started using Polymer.dart in your apps.
+ *
+ * * [polymer.dart package](http://pub.dartlang.org/packages/polymer):
+ * More details, such as the current major release number.
+ *
+ * * [Upgrading to Polymer.dart](http://www.dartlang.org/polymer-dart/upgrading-to-polymer-from-web-ui.html):
+ * Tips for converting your apps from Web UI to Polymer.dart.
  */
 library polymer;
 
diff --git a/pkg/polymer/lib/polymer_element.dart b/pkg/polymer/lib/polymer_element.dart
index 3f42390..a7ade34 100644
--- a/pkg/polymer/lib/polymer_element.dart
+++ b/pkg/polymer/lib/polymer_element.dart
@@ -7,10 +7,9 @@
 import 'dart:async';
 import 'dart:html';
 import 'dart:mirrors';
-import 'dart:js' as dartJs;
+import 'dart:js' as js;
 
 import 'package:custom_element/custom_element.dart';
-import 'package:js/js.dart' as js;
 import 'package:mdv/mdv.dart' show NodeBinding;
 import 'package:observe/observe.dart';
 import 'package:observe/src/microtask.dart';
@@ -87,15 +86,19 @@
     var declaration = getDeclaration(localName);
     if (declaration == null) return;
 
-    if (declaration.attributes['extends'] != null) {
-      var base = declaration.attributes['extends'];
+    var extendee = declaration.attributes['extends'];
+    if (extendee != null) {
       // Skip normal tags, only initialize parent custom elements.
-      if (base.contains('-')) _initialize(base);
+      if (extendee.contains('-')) _initialize(extendee);
     }
 
     _parseHostEvents(declaration);
     _parseLocalEvents(declaration);
     _publishAttributes(declaration);
+
+    var templateContent = declaration.query('template').content;
+    _shimStyling(templateContent, localName);
+
     _localNames.add(localName);
   }
 
@@ -151,15 +154,11 @@
       root.applyAuthorStyles = applyAuthorStyles;
       root.resetStyleInheritance = resetStyleInheritance;
 
-      var templateNode = declaration.children.firstWhere(
-          (n) => n.localName == 'template', orElse: () => null);
+      var templateNode = declaration.query('template');
       if (templateNode == null) return;
 
       // Create the contents of the element's ShadowRoot, and add them.
       root.nodes.add(instanceTemplate(templateNode));
-
-      var extendsName = declaration.attributes['extends'];
-      _shimCss(root, localName, extendsName);
     }
   }
 
@@ -174,31 +173,26 @@
   /**
    * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
    */
-  void _shimCss(ShadowRoot root, String localName, String extendsName) {
-    // TODO(terry): Need to detect if ShadowCSS.js has been loaded.  Under
-    //              Dartium this wouldn't exist.  However, dart:js isn't robust
-    //              to use to detect in both Dartium and dart2js if Platform is
-    //              defined.  This bug is described in
-    //              https://code.google.com/p/dart/issues/detail?id=12548
-    //              When fixed only use dart:js.  This is necessary under
-    //              Dartium (no compile) we want to run w/o the JS polyfill.
-    if (dartJs.context == null || !dartJs.context.hasProperty('Platform')) {
-      return;
-    }
+  void _shimStyling(DocumentFragment template, String localName) {
+    if (js.context == null) return;
 
-    var platform = js.context["Platform"];
+    var platform = js.context['Platform'];
     if (platform == null) return;
-    var shadowCss = platform.ShadowCSS;
+
+    var style = template.query('style');
+    if (style == null) return;
+
+    var shadowCss = platform['ShadowCSS'];
     if (shadowCss == null) return;
 
     // TODO(terry): Remove calls to shimShadowDOMStyling2 and replace with
     //              shimShadowDOMStyling when we support unwrapping dart:html
     //              Element to a JS DOM node.
-    var shimShadowDOMStyling2 = shadowCss.shimShadowDOMStyling2;
+    var shimShadowDOMStyling2 = shadowCss['shimShadowDOMStyling2'];
     if (shimShadowDOMStyling2 == null) return;
-    var style = root.query('style');
-    if (style == null) return;
-    var scopedCSS = shimShadowDOMStyling2(style.text, localName);
+
+    var scopedCSS = shimShadowDOMStyling2.apply(shadowCss,
+        [style.text, localName]);
 
     // TODO(terry): Remove when shimShadowDOMStyling is called we don't need to
     //              replace original CSS with scoped CSS shimShadowDOMStyling
diff --git a/pkg/polymer/lib/src/build/common.dart b/pkg/polymer/lib/src/build/common.dart
index 6233aa3..f5b4431 100644
--- a/pkg/polymer/lib/src/build/common.dart
+++ b/pkg/polymer/lib/src/build/common.dart
@@ -78,6 +78,9 @@
         checkDocType: options.isHtmlEntryPoint(id));
     });
   }
+
+  Future<bool> assetExists(AssetId id, Transform transform) =>
+      transform.getInput(id).then((_) => true).catchError((_) => false);
 }
 
 /** Create an [AssetId] for a [url] seen in the [source] asset. */
diff --git a/pkg/polymer/lib/src/build/linter.dart b/pkg/polymer/lib/src/build/linter.dart
index f65741a..3ed9c50 100644
--- a/pkg/polymer/lib/src/build/linter.dart
+++ b/pkg/polymer/lib/src/build/linter.dart
@@ -63,30 +63,41 @@
       Document document, AssetId sourceId, Transform transform,
       Set<AssetId> seen, [Map<String, _ElementSummary> elements]) {
     if (elements == null) elements = <String, _ElementSummary>{};
-    var logger = transform.logger;
-    // Note: the import order is relevant, so we visit in that order.
-    return Future.forEach(_getImportedIds(document, sourceId, logger), (id) {
-      if (seen.contains(id)) return new Future.value(null);
-      seen.add(id);
-      return readAsHtml(id, transform)
-        .then((doc) => _collectElements(doc, id, transform, seen, elements));
-    }).then((_) {
-      _addElements(document, logger, elements);
-      return elements;
-    });
+    return _getImportedIds(document, sourceId, transform)
+        // Note: the import order is relevant, so we visit in that order.
+        .then((ids) => Future.forEach(ids,
+              (id) => _readAndCollectElements(id, transform, seen, elements)))
+        .then((_) => _addElements(document, transform.logger, elements))
+        .then((_) => elements);
   }
 
-  List<AssetId> _getImportedIds(
-      Document document, AssetId sourceId, TranformLogger logger) {
+  Future _readAndCollectElements(AssetId id, Transform transform,
+      Set<AssetId> seen, Map<String, _ElementSummary> elements) {
+    if (id == null || seen.contains(id)) return new Future.value(null);
+    seen.add(id);
+    return readAsHtml(id, transform).then(
+        (doc) => _collectElements(doc, id, transform, seen, elements));
+  }
+
+  Future<List<AssetId>> _getImportedIds(
+      Document document, AssetId sourceId, Tranform transform) {
     var importIds = [];
+    var logger = transform.logger;
     for (var tag in document.queryAll('link')) {
       if (tag.attributes['rel'] != 'import') continue;
       var href = tag.attributes['href'];
-      var id = resolve(sourceId, href, logger, tag.sourceSpan);
+      var span = tag.sourceSpan;
+      var id = resolve(sourceId, href, logger, span);
       if (id == null) continue;
-      importIds.add(id);
+      importIds.add(assetExists(id, transform).then((exists) {
+        if (exists) return id;
+        if (sourceId == transform.primaryInput.id) {
+          logger.error('couldn\'t find imported asset "${id.path}" in package '
+              '"${id.package}".', span);
+        }
+      }));
     }
-    return importIds;
+    return Future.wait(importIds);
   }
 
   void _addElements(Document document, TransformLogger logger,
diff --git a/pkg/polymer/lib/src/build/polyfill_injector.dart b/pkg/polymer/lib/src/build/polyfill_injector.dart
index 7c3d3cf..d0e81ee 100644
--- a/pkg/polymer/lib/src/build/polyfill_injector.dart
+++ b/pkg/polymer/lib/src/build/polyfill_injector.dart
@@ -34,7 +34,6 @@
     return readPrimaryAsHtml(transform).then((document) {
       bool shadowDomFound = false;
       bool jsInteropFound = false;
-      bool pkgJsInteropFound = false;
       bool dartScriptTags = false;
 
       for (var tag in document.queryAll('script')) {
@@ -43,8 +42,6 @@
           var last = src.split('/').last;
           if (last == 'interop.js') {
             jsInteropFound = true;
-          } else if (last == 'dart_interop.js') {
-            pkgJsInteropFound = true;
           } else if (_shadowDomJS.hasMatch(last)) {
             shadowDomFound = true;
           }
@@ -61,12 +58,6 @@
         return;
       }
 
-      if (!pkgJsInteropFound) {
-        // JS interop code is required for Polymer CSS shimming.
-        document.body.nodes.insert(0, parseFragment(
-            '<script src="packages/js/dart_interop.js"></script>\n'));
-      }
-
       if (!jsInteropFound) {
         // JS interop code is required for Polymer CSS shimming.
         document.body.nodes.insert(0, parseFragment(
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index fd765fd..4d93ad5 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -14,7 +14,6 @@
   custom_element: any
   html5lib: any
   html_import: any
-  js: any
   logging: any
   mdv: any
   observe: any
diff --git a/pkg/polymer/test/build/all_phases_test.dart b/pkg/polymer/test/build/all_phases_test.dart
index e35347a..1c2dccc 100644
--- a/pkg/polymer/test/build/all_phases_test.dart
+++ b/pkg/polymer/test/build/all_phases_test.dart
@@ -37,7 +37,6 @@
           '<!DOCTYPE html><html><head></head><body>'
           '$SHADOW_DOM_TAG'
           '$INTEROP_TAG'
-          '$PKG_JS_INTEROP_TAG'
           '<script type="application/dart" '
           'src="test.html_bootstrap.dart"></script>'
           '<script src="packages/browser/dart.js"></script>'
@@ -70,7 +69,6 @@
           '<!DOCTYPE html><html><head></head><body>'
           '$SHADOW_DOM_TAG'
           '$INTEROP_TAG'
-          '$PKG_JS_INTEROP_TAG'
           '<script type="application/dart" '
           'src="test.html_bootstrap.dart"></script>'
           '<script src="packages/browser/dart.js"></script>'
@@ -110,7 +108,6 @@
           '<!DOCTYPE html><html><head></head><body>'
           '$SHADOW_DOM_TAG'
           '$INTEROP_TAG'
-          '$PKG_JS_INTEROP_TAG'
           '<div></div>'
           '<script type="application/dart" '
           'src="test.html_bootstrap.dart"></script>'
@@ -162,7 +159,6 @@
           '<!DOCTYPE html><html><head></head><body>'
           '$SHADOW_DOM_TAG'
           '$INTEROP_TAG'
-          '$PKG_JS_INTEROP_TAG'
           '<polymer-element>1</polymer-element>'
           '<script type="application/dart" '
           'src="index.html_bootstrap.dart"></script>'
diff --git a/pkg/polymer/test/build/common.dart b/pkg/polymer/test/build/common.dart
index b855938..d725823 100644
--- a/pkg/polymer/test/build/common.dart
+++ b/pkg/polymer/test/build/common.dart
@@ -106,6 +106,3 @@
     '<script src="packages/shadow_dom/shadow_dom.debug.js"></script>\n';
 
 const INTEROP_TAG = '<script src="packages/browser/interop.js"></script>\n';
-
-const PKG_JS_INTEROP_TAG =
-    '<script src="packages/js/dart_interop.js"></script>\n';
diff --git a/pkg/polymer/test/build/linter_test.dart b/pkg/polymer/test/build/linter_test.dart
index c2eb75e..e4f3630 100644
--- a/pkg/polymer/test/build/linter_test.dart
+++ b/pkg/polymer/test/build/linter_test.dart
@@ -66,6 +66,17 @@
             '(second definition). (lib/test.html 2 0)'
       });
 
+    _testLinter('non existing file', {
+        'a|lib/test.html': '''<html>
+            <link rel="import" href="b.html">
+            <polymer-element name="x-a"></polymer-element>
+            </html>'''.replaceAll('            ', ''),
+      }, {
+        'a|lib/test.html.messages':
+            'error: couldn\'t find imported asset "lib/b.html" in package '
+            '"a". (lib/test.html 1 0)'
+      });
+
     _testLinter('other package', {
         'b|lib/b.html': '''<html>
             <polymer-element name="x-a"></polymer-element>
diff --git a/pkg/polymer/test/build/polyfill_injector_test.dart b/pkg/polymer/test/build/polyfill_injector_test.dart
index 124b21b..608825e 100644
--- a/pkg/polymer/test/build/polyfill_injector_test.dart
+++ b/pkg/polymer/test/build/polyfill_injector_test.dart
@@ -37,7 +37,7 @@
     }, {
       'a|web/test.html':
           '<!DOCTYPE html><html><head></head><body>'
-          '$SHADOW_DOM_TAG$INTEROP_TAG$PKG_JS_INTEROP_TAG'
+          '$SHADOW_DOM_TAG$INTEROP_TAG'
           '<script type="application/dart" src="a.dart"></script>'
           '</body></html>',
     });
@@ -48,14 +48,12 @@
           '<script type="application/dart" src="a.dart"></script>'
           '$SHADOW_DOM_TAG'
           '$INTEROP_TAG'
-          '$PKG_JS_INTEROP_TAG',
     }, {
       'a|web/test.html':
           '<!DOCTYPE html><html><head></head><body>'
           '<script type="application/dart" src="a.dart"></script>'
           '$SHADOW_DOM_TAG'
           '$INTEROP_TAG'
-          '$PKG_JS_INTEROP_TAG'
           '</body></html>',
     });
 }
diff --git a/pkg/polymer_expressions/README.md b/pkg/polymer_expressions/README.md
index 5a7e9b2..9cc3da4 100644
--- a/pkg/polymer_expressions/README.md
+++ b/pkg/polymer_expressions/README.md
@@ -1,8 +1,25 @@
 polymer_expressions
 ===================
 
-Polymer Expressions are an expressive syntax that can be used in templates in
-Dart. Polymer Expressions allow you to write complex binding expressions, with
+
+Polymer expressions are an expressive syntax that can be used in HTML templates
+with Dart.
+
+Templates are one feature of Polymer.dart, which is a set of comprehensive UI
+and utility components for building web applications.
+This package is automatically included with the
+[Polymer](https://pub.dartlang.org/packages/polymer) package
+because Polymer expressions are the default expression syntax
+in Polymer Dart apps.
+The [Polymer.dart homepage][home_page]
+contains a list of features, project status,
+installation instructions, tips for upgrading from Web UI,
+and links to other documentation.
+
+
+## Overview
+
+Polymer expressions allow you to write complex binding expressions, with
 property access, function invocation, list/map indexing, and two-way filtering
 like:
 
@@ -10,12 +27,10 @@
     {{ person.title + " " + person.getFullName() | upppercase }}
 ```
 
-## Overview
-
 ### Model-Driven Views (MDV)
-[MDV][mdv] allows you to define templates directly in HTML that are rendered by the
-browser into the DOM. Templates are bound to a data model, and changes to the
-data are automatically reflected in the DOM, and changes in HTML inputs are
+[MDV][mdv] allows you to define templates directly in HTML that are rendered by
+the browser into the DOM. Templates are bound to a data model, and changes to
+the data are automatically reflected in the DOM, and changes in HTML inputs are
 assigned back into the model. The template and model are bound together via
 binding expressions that are evaluated against the model. These binding
 expressions are placed in double-curly-braces, or "mustaches".
diff --git a/pkg/polymer_expressions/lib/eval.dart b/pkg/polymer_expressions/lib/eval.dart
index 7341e05..b76b3b8 100644
--- a/pkg/polymer_expressions/lib/eval.dart
+++ b/pkg/polymer_expressions/lib/eval.dart
@@ -595,12 +595,16 @@
 }
 
 /**
- * A comprehension declaration ("a in b").
+ * A comprehension declaration ("a in b"). [identifier] is the loop variable
+ * that's added to the scope during iteration. [iterable] is the set of
+ * objects to iterate over.
  */
 class Comprehension {
   final String identifier;
   final Iterable iterable;
-  Comprehension(this.identifier, this.iterable);
+
+  Comprehension(this.identifier, Iterable iterable)
+      : iterable = (iterable != null) ? iterable : const [];
 }
 
 /**
diff --git a/pkg/polymer_expressions/lib/polymer_expressions.dart b/pkg/polymer_expressions/lib/polymer_expressions.dart
index dd7d7af..d74daca 100644
--- a/pkg/polymer_expressions/lib/polymer_expressions.dart
+++ b/pkg/polymer_expressions/lib/polymer_expressions.dart
@@ -2,6 +2,29 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * A binding delegate used with Polymer elements that
+ * allows for complex binding expressions, including
+ * property access, function invocation,
+ * list/map indexing, and two-way filtering.
+ *
+ * When you install polymer.dart,
+ * polymer_expressions is automatically installed as well.
+ *
+ * Polymer expressions are part of the Polymer.dart project.
+ * Refer to the
+ * [Polymer.dart](http://www.dartlang.org/polymer-dart/)
+ * homepage for example code, project status, and
+ * information about how to get started using Polymer.dart in your apps.
+ * 
+ * ## Other resources
+ *
+ * The
+ * [Polymer expressions](http://pub.dartlang.org/packages/polymer_expressions)
+ * pub repository contains detailed documentation about using polymer
+ * expressions.
+ */
+
 library polymer_expressions;
 
 import 'dart:async';
diff --git a/pkg/polymer_expressions/pubspec.yaml b/pkg/polymer_expressions/pubspec.yaml
index d6322cf..3a1d563 100644
--- a/pkg/polymer_expressions/pubspec.yaml
+++ b/pkg/polymer_expressions/pubspec.yaml
@@ -1,7 +1,7 @@
 name: polymer_expressions
 author: Web UI Authors <html-dev@dartlang.org>
 description: An expressive custom binding syntax for MDV templates
-homepage: http://www.dartlang.org/
+homepage: http://www.dartlang.org/polymer-dart/
 dependencies:
   browser: any
   mdv: any
diff --git a/pkg/polymer_expressions/test/eval_test.dart b/pkg/polymer_expressions/test/eval_test.dart
index ece4396..96fcd2d 100644
--- a/pkg/polymer_expressions/test/eval_test.dart
+++ b/pkg/polymer_expressions/test/eval_test.dart
@@ -197,7 +197,7 @@
       var scope = new Scope(variables: {'items': null});
       var comprehension = eval(parse('item in items'), scope);
       expect(comprehension, isNotNull);
-      expect(comprehension.iterable, null);
+      expect(comprehension.iterable, []);
     });
 
   });
diff --git a/pkg/polymer_expressions/test/syntax_test.dart b/pkg/polymer_expressions/test/syntax_test.dart
index 791a021..82c3e60 100644
--- a/pkg/polymer_expressions/test/syntax_test.dart
+++ b/pkg/polymer_expressions/test/syntax_test.dart
@@ -15,19 +15,23 @@
   mdv.initialize();
   useHtmlEnhancedConfiguration();
 
-  group('syntax', () {
+  group('PolymerExpressions', () {
+    var testDiv;
+
     setUp(() {
-      document.body.nodes.add(new Element.html('''
-          <template id="test" bind>
-            <input id="input" value="{{ firstName }}">
-          </template>'''));
+      document.body.append(testDiv = new DivElement());
     });
 
     tearDown(() {
-      query('#test')..unbindAll()..remove();
+      testDiv.remove();
+      testDiv = null;
     });
 
     test('should make two-way bindings to inputs', () {
+      testDiv.nodes.add(new Element.html('''
+          <template id="test" bind>
+            <input id="input" value="{{ firstName }}">
+          </template>'''));
       var person = new Person('John', 'Messerly', ['A', 'B', 'C']);
       query('#test')
           ..bindingDelegate = new PolymerExpressions()
@@ -44,6 +48,20 @@
       });
     });
 
+    test('should handle null collections in "in" expressions', () {
+      testDiv.nodes.add(new Element.html('''
+          <template id="test" bind>
+            <template repeat="{{ item in items }}">
+              {{ item }}
+            </template>
+          </template>'''));      
+      query('#test')
+          ..bindingDelegate = new PolymerExpressions(globals: {'items': null})
+          ..model = null;
+      // the template should be the only node
+      expect(testDiv.nodes.length, 1);
+      expect(testDiv.nodes[0].id, 'test');
+    });
   });
 }
 
diff --git a/pkg/unittest/lib/test_controller.js b/pkg/unittest/lib/test_controller.js
index fe5cf93..4862e03 100644
--- a/pkg/unittest/lib/test_controller.js
+++ b/pkg/unittest/lib/test_controller.js
@@ -64,6 +64,11 @@
 
 function notifyDone() {
   if (testRunner) testRunner.notifyDone();
+
+  // TODO(ricow): REMOVE, debug info, see issue 13292
+  if (!testRunner) {
+    dartPrint('Calling notifyDone()');
+  }
   // To support in browser launching of tests we post back start and result
   // messages to the window.opener.
   var driver = getDriverWindow();
@@ -73,6 +78,10 @@
 }
 
 function processMessage(msg) {
+  // TODO(ricow): REMOVE, debug info, see issue 13292
+  if (!testRunner) {
+    dartPrint('processMessage(): ' + msg);
+  }
   if (typeof msg != 'string') return;
   if (msg == 'unittest-suite-done') {
     notifyDone();
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 94ca09e..4239279 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -844,8 +844,9 @@
 }
 
 
-void DartUtils::SetOriginalWorkingDirectory() {
+bool DartUtils::SetOriginalWorkingDirectory() {
   original_working_directory = Directory::Current();
+  return original_working_directory != NULL;
 }
 
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index d4fc347..ff17d1a 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -163,7 +163,7 @@
   // Create a new Dart InternalError object with the provided message.
   static Dart_Handle NewInternalError(const char* message);
 
-  static void SetOriginalWorkingDirectory();
+  static bool SetOriginalWorkingDirectory();
 
   static const char* MapLibraryUrl(CommandLineOptions* url_mapping,
                                    const char* url_string);
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 0e813eb..b854e3d 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -719,6 +719,13 @@
     }
   }
 
+  if (!DartUtils::SetOriginalWorkingDirectory()) {
+    OSError err;
+    fprintf(stderr, "Error determinig current directory: %s\n", err.message());
+    fflush(stderr);
+    return kErrorExitCode;
+  }
+
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
 
   // Initialize the Dart VM.
@@ -732,8 +739,6 @@
     return kErrorExitCode;
   }
 
-  DartUtils::SetOriginalWorkingDirectory();
-
   // Start the debugger wire protocol handler if necessary.
   if (start_debugger) {
     ASSERT(debug_port >= 0);
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index bd47064..605176a 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -147,8 +147,8 @@
  * Returns an array of numbers. Null values indicate the beginning of
  * a new line. The first number after null is the line number.
  * The line number is followed by pairs of numbers, with the first value
- * being the "token offset" and the second value being the character offset
- * of the token relative to the beginning of the script.
+ * being the "token offset" and the second value being the column number
+ * of the token.
  * The "token offset" is a value that is used to indicate a location
  * in code, similarly to a "PC" address.
  * Source lines with no tokens are omitted.
diff --git a/runtime/include/dart_mirrors_api.h b/runtime/include/dart_mirrors_api.h
index 7805449..23ec4e9 100644
--- a/runtime/include/dart_mirrors_api.h
+++ b/runtime/include/dart_mirrors_api.h
@@ -11,9 +11,14 @@
 
 
 /**
- * Returns the class name for the provided class or interface.
+ * Returns the class name for the provided class.
  */
-DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz);
+DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle type);
+
+/**
+ * Returns the qualified class name for the provided class.
+ */
+DART_EXPORT Dart_Handle Dart_QualifiedClassName(Dart_Handle type);
 
 /**
  * Returns a list of the names of all functions or methods declared in
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 8bed356..9ae7d17 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -259,7 +259,7 @@
   args.SetAt(0, field_ref);
   args.SetAt(1, name);
   args.SetAt(2, owner_mirror);
-  args.SetAt(3, Instance::Handle());  // Null for type.
+  args.SetAt(3, Object::null_instance());  // Null for type.
   args.SetAt(4, Bool::Get(field.is_static()));
   args.SetAt(5, Bool::Get(field.is_final()));
 
@@ -435,9 +435,16 @@
 
 
 DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 1) {
-  const MirrorReference& decl_ref =
-      MirrorReference::CheckedHandle(arguments->NativeArgAt(0));
-  const Object& decl = Object::Handle(decl_ref.referent());
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
+  Object& decl = Object::Handle();
+  if (reflectee.IsMirrorReference()) {
+    const MirrorReference& decl_ref = MirrorReference::Cast(reflectee);
+    decl = decl_ref.referent();
+  } else if (reflectee.IsTypeParameter()) {
+    decl = reflectee.raw();
+  } else {
+    UNREACHABLE();
+  }
 
   Class& klass = Class::Handle();
   Library& library = Library::Handle();
@@ -453,6 +460,9 @@
     library = klass.library();
   } else if (decl.IsLibrary()) {
     library ^= decl.raw();
+  } else if (decl.IsTypeParameter()) {
+    klass ^= TypeParameter::Cast(decl).parameterized_class();
+    library = klass.library();
   } else {
     return Object::empty_array().raw();
   }
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 534ded4..0487b58 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -769,7 +769,6 @@
 
   Map<Symbol, Mirror> get members => new Map<Symbol,Mirror>();
   Map<Symbol, MethodMirror> get constructors => new Map<Symbol,MethodMirror>();
-  final Map<Symbol, TypeVariableMirror> typeVariables = const {};
 
   String toString() => "FunctionTypeMirror on '${_n(simpleName)}'";
 
@@ -847,11 +846,6 @@
     return _upperBound;
   }
 
-  List<InstanceMirror> get metadata {
-    throw new UnimplementedError(
-        'TypeVariableMirror.metadata is not implemented');
-  }
-
   bool get isOriginalDeclaration => true;
   ClassMirror get originalDeclaration => this;
 
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index de01c97..16dd211 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -187,7 +187,7 @@
 
       Exceptions::CreateAndThrowTypeError(
           location, instance_type_name, type_name,
-          dst_name, String::Handle());
+          dst_name, Object::null_string());
     } else {
       ASSERT(FLAG_enable_type_checks);
       malformed_error_message = String::New(malformed_error.ToErrorCString());
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 1ed67c6..6add296 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -48,9 +48,6 @@
 # Skip until we stabilize language tests.
 *: Skip
 
-[ $arch == x64 && $mode == debug ]
-cc/FindCodeObject: Pass, Timeout  # Issue 13144
-
 [ $arch == simarm ]
 dart/isolate_mirror_local_test: Skip
 
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 82e5e5c..8012de3 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -91,6 +91,7 @@
 }
 #endif
 
+
 void CPUFeatures::InitOnce() {
 #if defined(USING_SIMULATOR)
   integer_division_supported_ = true;
@@ -1592,8 +1593,12 @@
 
 void Assembler::CompareObject(Register rn, const Object& object) {
   ASSERT(rn != IP);
-  LoadObject(IP, object);
-  cmp(rn, ShifterOperand(IP));
+  if (object.IsSmi()) {
+    CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw()));
+  } else {
+    LoadObject(IP, object);
+    cmp(rn, ShifterOperand(IP));
+  }
 }
 
 
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index efdb624..11639c1 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -78,28 +78,30 @@
 
     // These objects and labels need to be accessible through every pool-pointer
     // at the same index.
-    object_pool_.Add(Object::Handle(), Heap::kOld);
+    object_pool_.Add(Object::null_object(), Heap::kOld);
     patchable_pool_entries_.Add(kNotPatchable);
+    // Not adding Object::null() to the index table. It is at index 0 in the
+    // object pool, but the HashMap uses 0 to indicate not found.
 
     object_pool_.Add(Bool::True(), Heap::kOld);
     patchable_pool_entries_.Add(kNotPatchable);
+    object_pool_index_table_.Insert(ObjIndexPair(Bool::True().raw(), 1));
 
     object_pool_.Add(Bool::False(), Heap::kOld);
     patchable_pool_entries_.Add(kNotPatchable);
+    object_pool_index_table_.Insert(ObjIndexPair(Bool::False().raw(), 2));
 
     if (StubCode::UpdateStoreBuffer_entry() != NULL) {
       FindExternalLabel(&StubCode::UpdateStoreBufferLabel(), kNotPatchable);
-      patchable_pool_entries_.Add(kNotPatchable);
     } else {
-      object_pool_.Add(Object::Handle(), Heap::kOld);
+      object_pool_.Add(Object::null_object(), Heap::kOld);
       patchable_pool_entries_.Add(kNotPatchable);
     }
 
     if (StubCode::CallToRuntime_entry() != NULL) {
       FindExternalLabel(&StubCode::CallToRuntimeLabel(), kNotPatchable);
-      patchable_pool_entries_.Add(kNotPatchable);
     } else {
-      object_pool_.Add(Object::Handle(), Heap::kOld);
+      object_pool_.Add(Object::null_object(), Heap::kOld);
       patchable_pool_entries_.Add(kNotPatchable);
     }
   }
@@ -2172,16 +2174,30 @@
   ASSERT(Isolate::Current() != Dart::vm_isolate());
   ASSERT(!object_pool_.IsNull());
 
-  // TODO(zra): This can be slow. Add a hash map from obj.raw() to
-  // object pool indexes to speed lookup.
-  for (int i = 0; i < object_pool_.Length(); i++) {
-    if ((object_pool_.At(i) == obj.raw()) &&
-        (patchable_pool_entries_[i] != kPatchable)) {
-      return i;
+  // If the object is not patchable, check if we've already got it in the
+  // object pool.
+  if (patchable == kNotPatchable) {
+    // Special case for Object::null(), which is always at object_pool_ index 0
+    // because Lookup() below returns 0 when the object is not mapped in the
+    // table.
+    if (obj.raw() == Object::null()) {
+      return 0;
+    }
+
+    intptr_t idx = object_pool_index_table_.Lookup(obj.raw());
+    if (idx != 0) {
+      ASSERT(patchable_pool_entries_[idx] == kNotPatchable);
+      return idx;
     }
   }
+
   object_pool_.Add(obj, Heap::kOld);
   patchable_pool_entries_.Add(patchable);
+  if (patchable == kNotPatchable) {
+    // The object isn't patchable. Record the index for fast lookup.
+    object_pool_index_table_.Insert(
+        ObjIndexPair(obj.raw(), object_pool_.Length() - 1));
+  }
   return object_pool_.Length() - 1;
 }
 
@@ -2196,6 +2212,8 @@
   // The address is stored in the object array as a RawSmi.
   const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address));
   if (patchable == kNotPatchable) {
+    // If the call site is not patchable, we can try to re-use an existing
+    // entry.
     return FindObject(smi, kNotPatchable);
   }
   // If the call is patchable, do not reuse an existing entry since each
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 96921ee..4aa070c 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -12,6 +12,7 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/constants_x64.h"
+#include "vm/hash_map.h"
 
 namespace dart {
 
@@ -837,6 +838,47 @@
   // Patchability of pool entries.
   GrowableArray<Patchability> patchable_pool_entries_;
 
+  // Pair type parameter for DirectChainedHashMap.
+  class ObjIndexPair {
+   public:
+    // TODO(zra): A WeakTable should be used here instead, but then it would
+    // also have to be possible to register and de-register WeakTables with the
+    // heap. Also, the Assembler would need to become a StackResource.
+    // Issue 13305. In the meantime...
+    // CAUTION: the RawObject* below is only safe because:
+    // The HashMap that will use this pair type will not contain any RawObject*
+    // keys that are not in the object_pool_ array. Since the keys will be
+    // visited by the GC when it visits the object_pool_, and since all objects
+    // in the object_pool_ are Old (and so will not be moved) the GC does not
+    // also need to visit the keys here in the HashMap.
+
+    // Typedefs needed for the DirectChainedHashMap template.
+    typedef RawObject* Key;
+    typedef intptr_t Value;
+    typedef ObjIndexPair Pair;
+
+    ObjIndexPair(Key key, Value value) : key_(key), value_(value) { }
+
+    static Key KeyOf(Pair kv) { return kv.key_; }
+
+    static Value ValueOf(Pair kv) { return kv.value_; }
+
+    static intptr_t Hashcode(Key key) {
+      return reinterpret_cast<intptr_t>(key) >> kObjectAlignmentLog2;
+    }
+
+    static inline bool IsKeyEqual(Pair kv, Key key) {
+      return kv.key_ == key;
+    }
+
+   private:
+    Key key_;
+    Value value_;
+  };
+
+  // Hashmap for fast lookup in object pool.
+  DirectChainedHashMap<ObjIndexPair> object_pool_index_table_;
+
   int prologue_offset_;
 
   class CodeComment : public ZoneAllocated {
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 7a673f9..0ba9638 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -505,7 +505,7 @@
 DART_EXPORT Dart_Handle Dart_HandleFromPersistent(
     Dart_PersistentHandle object) {
   Isolate* isolate = Isolate::Current();
-  DARTSCOPE(isolate);
+  CHECK_ISOLATE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   ASSERT(state->IsValidPersistentHandle(object));
@@ -517,7 +517,7 @@
 DART_EXPORT Dart_Handle Dart_HandleFromWeakPersistent(
     Dart_WeakPersistentHandle object) {
   Isolate* isolate = Isolate::Current();
-  DARTSCOPE(isolate);
+  CHECK_ISOLATE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   ASSERT(state->IsValidWeakPersistentHandle(object) ||
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index dda6809..c3bc011 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -285,6 +285,12 @@
   EXPECT_VALID(Dart_StringToCString(cls_name, &cls_name_cstr));
   EXPECT_STREQ("bool", cls_name_cstr);
 
+  Dart_Handle qual_cls_name = Dart_QualifiedClassName(cls);
+  EXPECT_VALID(qual_cls_name);
+  const char* qual_cls_name_cstr = "";
+  EXPECT_VALID(Dart_StringToCString(qual_cls_name, &qual_cls_name_cstr));
+  EXPECT_STREQ("Library:'dart:core' Class: bool", qual_cls_name_cstr);
+
   // Errors propagate.
   Dart_Handle error = Dart_NewApiError("MyError");
   Dart_Handle error_cls = Dart_InstanceGetClass(error);
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 09e24c0..65eedb6 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -690,6 +690,7 @@
   const String& key = Symbols::Empty();
   const Object& line_separator = Object::Handle();
   const TokenStream& tkns = TokenStream::Handle(script.tokens());
+  int line_offset = script.line_offset();
   ASSERT(!tkns.IsNull());
   TokenStream::Iterator tkit(tkns, 0);
   int current_line = -1;
@@ -702,14 +703,19 @@
     if (token_line != current_line) {
       // emit line
       info.Add(line_separator);
-      info.Add(Smi::Handle(Smi::New(token_line)));
+      info.Add(Smi::Handle(Smi::New(token_line + line_offset)));
       current_line = token_line;
     }
     // TODO(hausner): Could optimize here by not reporting tokens
     // that will never be a location used by the debugger, e.g.
     // braces, semicolons, most keywords etc.
     info.Add(Smi::Handle(Smi::New(tkit.CurrentPosition())));
-    info.Add(Smi::Handle(Smi::New(s.current_token().offset)));
+    int column = s.current_token().position.column;
+    // On the first line of the script we must add the column offset.
+    if (token_line == 1) {
+      column += script.col_offset();
+    }
+    info.Add(Smi::Handle(Smi::New(column)));
     s.Scan();
     tkit.Advance();
   }
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 9ed4e93..00df26b 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -1740,8 +1740,7 @@
           __ ldr(value_cid_reg,
                  FieldAddress(value_reg, TypedData::length_offset()));
         }
-        __ LoadImmediate(IP, field_length);
-        __ cmp(value_cid_reg, ShifterOperand(IP));
+        __ CompareImmediate(value_cid_reg, field_length);
         if (ok_is_fall_through) {
           __ b(fail, NE);
         }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 3673b92..f4863d4 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -109,7 +109,7 @@
   if (!message->IsOOB()) {
     receive_port = DartLibraryCalls::LookupReceivePort(message->dest_port());
     if (receive_port.IsError()) {
-      return ProcessUnhandledException(Instance::Handle(),
+      return ProcessUnhandledException(Object::null_instance(),
                                        Error::Cast(receive_port));
     }
     if (receive_port.IsNull()) {
@@ -124,7 +124,8 @@
   const Object& msg_obj = Object::Handle(reader.ReadObject());
   if (msg_obj.IsError()) {
     // An error occurred while reading the message.
-    return ProcessUnhandledException(Instance::Handle(), Error::Cast(msg_obj));
+    return ProcessUnhandledException(Object::null_instance(),
+                                     Error::Cast(msg_obj));
   }
   if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
     // TODO(turnidge): We need to decide what an isolate does with
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index 4fd535f..673621d 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -35,6 +35,19 @@
   }
 }
 
+DART_EXPORT Dart_Handle Dart_QualifiedClassName(Dart_Handle object) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object));
+  if (obj.IsType() || obj.IsClass()) {
+    const Class& cls = (obj.IsType()) ?
+        Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj);
+    return Dart_NewStringFromCString(cls.ToCString());
+  } else {
+    RETURN_TYPE_ERROR(isolate, object, Class/Type);
+  }
+}
+
 // --- Function and Variable Reflection ---
 
 // Outside of the vm, we expose setter names with a trailing '='.
@@ -234,7 +247,7 @@
 #endif
     return Api::NewHandle(isolate, owner.library());
   } else {
-    return Api::NewHandle(isolate, owner.raw());
+    return Api::NewHandle(isolate, owner.RareType());
   }
 }
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index bdfac3c..c3d31e7 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -842,7 +842,7 @@
   ASSERT(!core_lib.IsNull());
 
   const GrowableObjectArray& pending_classes =
-      GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld));
+      GrowableObjectArray::Handle(GrowableObjectArray::New());
   object_store->set_pending_classes(pending_classes);
 
   Context& context = Context::Handle(Context::New(0, Heap::kOld));
@@ -854,7 +854,7 @@
   String& name = String::Handle();
   cls = object_store->array_class();  // Was allocated above.
   RegisterPrivateClass(cls, Symbols::ObjectArray(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   // We cannot use NewNonParameterizedType(cls), because Array is parameterized.
   type ^= Type::New(Object::Handle(cls.raw()),
                     TypeArguments::Handle(),
@@ -865,7 +865,7 @@
 
   cls = object_store->growable_object_array_class();  // Was allocated above.
   RegisterPrivateClass(cls, Symbols::GrowableObjectArray(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Array>(kImmutableArrayCid);
   object_store->set_immutable_array_class(cls);
@@ -873,36 +873,36 @@
   ASSERT(object_store->immutable_array_class() != object_store->array_class());
   cls.set_is_prefinalized();
   RegisterPrivateClass(cls, Symbols::ImmutableArray(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = object_store->one_byte_string_class();  // Was allocated above.
   RegisterPrivateClass(cls, Symbols::OneByteString(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = object_store->two_byte_string_class();  // Was allocated above.
   RegisterPrivateClass(cls, Symbols::TwoByteString(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::NewStringClass(kExternalOneByteStringCid);
   object_store->set_external_one_byte_string_class(cls);
   RegisterPrivateClass(cls, Symbols::ExternalOneByteString(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::NewStringClass(kExternalTwoByteStringCid);
   object_store->set_external_two_byte_string_class(cls);
   RegisterPrivateClass(cls, Symbols::ExternalTwoByteString(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Stacktrace>();
   object_store->set_stacktrace_class(cls);
   RegisterClass(cls, Symbols::StackTrace(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   // Super type set below, after Object is allocated.
 
   cls = Class::New<JSRegExp>();
   object_store->set_jsregexp_class(cls);
   RegisterPrivateClass(cls, Symbols::JSSyntaxRegExp(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   // Initialize the base interfaces used by the core VM classes.
 
@@ -915,67 +915,67 @@
   cls.set_name(Symbols::Object());
   cls.set_is_prefinalized();
   core_lib.AddClass(cls);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_object_type(type);
 
   cls = Class::New<Bool>();
   object_store->set_bool_class(cls);
   RegisterClass(cls, Symbols::Bool(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Instance>(kNullCid);
   cls.set_is_prefinalized();
   object_store->set_null_class(cls);
   RegisterClass(cls, Symbols::Null(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = object_store->type_class();
   RegisterPrivateClass(cls, Symbols::Type(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = object_store->type_parameter_class();
   RegisterPrivateClass(cls, Symbols::TypeParameter(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = object_store->bounded_type_class();
   RegisterPrivateClass(cls, Symbols::BoundedType(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = object_store->mixin_app_type_class();
   RegisterPrivateClass(cls, Symbols::MixinAppType(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Integer>();
   object_store->set_integer_implementation_class(cls);
   RegisterPrivateClass(cls, Symbols::IntegerImplementation(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Smi>();
   object_store->set_smi_class(cls);
   RegisterPrivateClass(cls, Symbols::_Smi(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Mint>();
   object_store->set_mint_class(cls);
   RegisterPrivateClass(cls, Symbols::_Mint(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Bigint>();
   object_store->set_bigint_class(cls);
   RegisterPrivateClass(cls, Symbols::_Bigint(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   cls = Class::New<Double>();
   object_store->set_double_class(cls);
   RegisterPrivateClass(cls, Symbols::_Double(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 
   // Abstract super class for all signature classes.
   cls = Class::New<Instance>(kIllegalCid);
   cls.set_is_prefinalized();
   RegisterPrivateClass(cls, Symbols::FunctionImpl(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_function_impl_type(type);
 
@@ -1033,14 +1033,14 @@
   index = kTypedData##clazz##ViewCid - kTypedDataInt8ArrayCid;                 \
   typed_data_classes.SetAt(index, cls);                                        \
   RegisterPrivateClass(cls, Symbols::_##clazz##View(), lib);                   \
-  pending_classes.Add(cls, Heap::kOld);                                        \
+  pending_classes.Add(cls);                                                    \
 
   CLASS_LIST_TYPED_DATA(REGISTER_TYPED_DATA_VIEW_CLASS);
   cls = Class::NewTypedDataViewClass(kByteDataViewCid);
   index = kByteDataViewCid - kTypedDataInt8ArrayCid;
   typed_data_classes.SetAt(index, cls);
   RegisterPrivateClass(cls, Symbols::_ByteDataView(), lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
 #undef REGISTER_TYPED_DATA_VIEW_CLASS
 #define REGISTER_EXT_TYPED_DATA_CLASS(clazz)                                   \
   cls = Class::NewExternalTypedDataClass(kExternalTypedData##clazz##Cid);      \
@@ -1061,14 +1061,14 @@
   cls = Class::New<Instance>(kIllegalCid);
   RegisterClass(cls, Symbols::Float32x4(), lib);
   cls.set_is_prefinalized();
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_float32x4_type(type);
 
   cls = Class::New<Instance>(kIllegalCid);
   RegisterClass(cls, Symbols::Uint32x4(), lib);
   cls.set_is_prefinalized();
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_uint32x4_type(type);
 
@@ -1084,27 +1084,27 @@
   cls = Class::New<Instance>(kIllegalCid);
   cls.set_is_prefinalized();
   RegisterClass(cls, Symbols::Function(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_function_type(type);
 
   cls = Class::New<Number>();
   RegisterClass(cls, Symbols::Number(), core_lib);
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_number_type(type);
 
   cls = Class::New<Instance>(kIllegalCid);
   RegisterClass(cls, Symbols::Int(), core_lib);
   cls.set_is_prefinalized();
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_int_type(type);
 
   cls = Class::New<Instance>(kIllegalCid);
   RegisterClass(cls, Symbols::Double(), core_lib);
   cls.set_is_prefinalized();
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_double_type(type);
 
@@ -1112,7 +1112,7 @@
   cls = Class::New<Instance>(kIllegalCid);
   RegisterClass(cls, name, core_lib);
   cls.set_is_prefinalized();
-  pending_classes.Add(cls, Heap::kOld);
+  pending_classes.Add(cls);
   type = Type::NewNonParameterizedType(cls);
   object_store->set_string_type(type);
 
@@ -6546,6 +6546,21 @@
 }
 
 
+static RawString* MakeTypeParameterMetaName(const TypeParameter& param) {
+  const Array& parts = Array::Handle(Array::New(3));
+  String& part = String::Handle();
+  part ^= MakeClassMetaName(Class::Handle(param.parameterized_class()));
+  parts.SetAt(0, part);
+  // We need to choose something different from field/function names, because it
+  // is allowed to have type parameters and fields/functions with the same name
+  // in a class.
+  parts.SetAt(1, Symbols::Slash());
+  part ^= param.name();
+  parts.SetAt(2, part);
+  return String::ConcatAll(parts);
+}
+
+
 void Library::AddMetadata(const Class& cls,
                           const String& name,
                           intptr_t token_pos) const {
@@ -6584,6 +6599,15 @@
               token_pos);
 }
 
+
+void Library::AddTypeParameterMetadata(const TypeParameter& param,
+                                       intptr_t token_pos) const {
+  AddMetadata(Class::Handle(param.parameterized_class()),
+              String::Handle(MakeTypeParameterMetaName(param)),
+              token_pos);
+}
+
+
 void Library::AddLibraryMetadata(const Class& cls, intptr_t token_pos) const {
   AddMetadata(cls, Symbols::TopLevel(), token_pos);
 }
@@ -6598,6 +6622,8 @@
     return MakeFunctionMetaName(Function::Cast(obj));
   } else if (obj.IsLibrary()) {
     return Symbols::TopLevel().raw();
+  } else if (obj.IsTypeParameter()) {
+    return MakeTypeParameterMetaName(TypeParameter::Cast(obj));
   }
   UNIMPLEMENTED();
   return String::null();
@@ -6623,7 +6649,7 @@
 
 RawObject* Library::GetMetadata(const Object& obj) const {
   if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() &&
-      !obj.IsLibrary()) {
+      !obj.IsLibrary() && !obj.IsTypeParameter()) {
     return Object::null();
   }
   const String& metaname = String::Handle(MakeMetadataName(obj));
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a23c441..56ce807 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -337,6 +337,7 @@
   }
 
   static RawObject* null() { return null_; }
+
   static const Object& null_object() {
     ASSERT(null_object_ != NULL);
     return *null_object_;
@@ -357,6 +358,7 @@
     ASSERT(null_abstract_type_arguments_ != NULL);
     return *null_abstract_type_arguments_;
   }
+
   static const Array& empty_array() {
     ASSERT(empty_array_ != NULL);
     return *empty_array_;
@@ -2395,6 +2397,8 @@
   void AddFieldMetadata(const Field& field, intptr_t token_pos) const;
   void AddFunctionMetadata(const Function& func, intptr_t token_pos) const;
   void AddLibraryMetadata(const Class& cls, intptr_t token_pos) const;
+  void AddTypeParameterMetadata(const TypeParameter& param,
+                                intptr_t token_pos) const;
   RawObject* GetMetadata(const Object& obj) const;
 
   intptr_t num_anonymous_classes() const { return raw_ptr()->num_anonymous_; }
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 2cd3f23..81407aa 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -433,6 +433,7 @@
         name(NULL),
         default_value(NULL),
         metadata(NULL),
+        var(NULL),
         is_final(false),
         is_field_initializer(false) { }
   const AbstractType* type;
@@ -440,6 +441,7 @@
   const String* name;
   const Object* default_value;  // NULL if not an optional parameter.
   const Object* metadata;  // NULL if no metadata or metadata not evaluated.
+  LocalVariable* var;  // Scope variable allocated for this parameter.
   bool is_final;
   bool is_field_initializer;
 };
@@ -478,6 +480,20 @@
     AddFinalParameter(token_pos, &Symbols::This(), receiver_type);
   }
 
+
+  // Make the parameter variables visible/invisible.
+  // Field initializer parameters are always invisible.
+  void SetInvisible(bool invisible) {
+    const intptr_t num_params = parameters->length();
+    for (int i = 0; i < num_params; i++) {
+      ParamDesc& param = (*parameters)[i];
+      ASSERT(param.var != NULL);
+      if (!param.is_field_initializer) {
+        param.var->set_invisible(invisible);
+      }
+    }
+  }
+
   void SetImplicitlyFinal() {
     implicitly_final = true;
   }
@@ -2483,16 +2499,6 @@
 }
 
 
-// Helper function to make the first num_variables variables in the
-// given scope visible/invisible.
-static void SetInvisible(LocalScope* scope, int num_variables, bool invisible) {
-  ASSERT(num_variables <= scope->num_variables());
-  for (int i = 0; i < num_variables; i++) {
-    scope->VariableAt(i)->set_invisible(invisible);
-  }
-}
-
-
 void Parser::CheckRecursiveInvocation() {
   const GrowableObjectArray& pending_functions =
       GrowableObjectArray::Handle(
@@ -2568,14 +2574,13 @@
   // the scope so the expressions use the correct offsets for 'this' when
   // storing values. We make the formal parameters temporarily invisible
   // while parsing the instance field initializer expressions.
-  SetInvisible(current_block_->scope, params.parameters->length(), true);
+  params.SetInvisible(true);
   GrowableArray<Field*> initialized_fields;
   LocalVariable* receiver = current_block_->scope->VariableAt(0);
   OpenBlock();
   ParseInitializedInstanceFields(cls, receiver, &initialized_fields);
   // Make the parameters (which are in the outer scope) visible again.
-  SetInvisible(current_block_->scope->parent(),
-               params.parameters->length(), false);
+  params.SetInvisible(false);
 
   // Turn formal field parameters into field initializers or report error
   // if the function is not a constructor.
@@ -2592,13 +2597,12 @@
         }
         CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field);
         AstNode* instance = new LoadLocalNode(param.name_pos, receiver);
-        LocalVariable* p =
-            current_block_->scope->LookupVariable(*param.name, false);
-        ASSERT(p != NULL);
         // Initializing formals cannot be used in the explicit initializer
         // list, nor can they be used in the constructor body.
-        // Thus, make the parameter invisible.
-        p->set_invisible(true);
+        // Thus, they are set to be invisible when added to the scope.
+        LocalVariable* p = param.var;
+        ASSERT(p != NULL);
+        ASSERT(p->is_invisible());
         AstNode* value = new LoadLocalNode(param.name_pos, p);
         EnsureExpressionTemp();
         AstNode* initializer = new StoreInstanceFieldNode(
@@ -4243,7 +4247,7 @@
     AbstractType& type_parameter_bound = Type::Handle();
     do {
       ConsumeToken();
-      SkipMetadata();
+      const intptr_t metadata_pos = SkipMetadata();
       const intptr_t type_parameter_pos = TokenPos();
       String& type_parameter_name =
           *ExpectUserDefinedTypeIdentifier("type parameter expected");
@@ -4272,6 +4276,9 @@
                                           type_parameter_bound,
                                           type_parameter_pos);
       type_parameters_array.Add(type_parameter);
+      if (metadata_pos >= 0) {
+        library_.AddTypeParameterMetadata(type_parameter, metadata_pos);
+      }
       index++;
     } while (CurrentToken() == Token::kCOMMA);
     Token::Kind token = CurrentToken();
@@ -5171,9 +5178,13 @@
                "name '%s' already exists in scope",
                param_desc.name->ToCString());
     }
+    param_desc.var = parameter;
     if (param_desc.is_final) {
       parameter->set_is_final();
     }
+    if (param_desc.is_field_initializer) {
+      parameter->set_invisible(true);
+    }
   }
 }
 
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index e721cd7..cac6212 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -220,8 +220,8 @@
 }
 
 
-// Add variables that are declared in this scope to vars, then collect
-// variables of children, followed by siblings.
+// Add visible variables that are declared in this scope to vars, then
+// collect visible variables of children, followed by siblings.
 void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars,
                                        int16_t* scope_id) {
   (*scope_id)++;
@@ -242,7 +242,7 @@
   }
   for (int i = 0; i < this->variables_.length(); i++) {
     LocalVariable* var = variables_[i];
-    if (var->owner() == this) {
+    if ((var->owner() == this) && !var->is_invisible()) {
       if (!IsInternalIdentifier(var->name())) {
         // This is a regular Dart variable, either stack-based or captured.
         VarDesc desc;
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index edf6749..a8b8d70 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -70,6 +70,7 @@
   void set_invisible(bool value) {
     is_invisible_ = value;
   }
+  bool is_invisible() const { return is_invisible_; }
 
   bool IsConst() const {
     return const_value_ != NULL;
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index daf9daf..ea110ef 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -277,6 +277,11 @@
   /// apply is runtime helpers that the backend calls, but the
   /// optimizations don't see those calls.
   bool canBeUsedForGlobalOptimizations(Element element) => true;
+
+  /// Called when [enqueuer]'s queue is empty, but before it is closed.
+  /// This is used, for example, by the JS backend to enqueue additional
+  /// elements needed for reflection.
+  void onQueueEmpty(Enqueuer enqueuer) {}
 }
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index d4dfd77..55f167b 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -5,7 +5,8 @@
 library dart2js.cmdline;
 
 import 'dart:async';
-import 'dart:io';
+import 'dart:io'
+    show exit, File, FileMode, Options, Platform, RandomAccessFile;
 import 'dart:math' as math;
 
 import '../compiler.dart' as api;
@@ -562,7 +563,7 @@
 }
 
 void mainWithErrorHandler(Options options) {
-  new Future.sync(() => compilerMain(options)).catchError((exception) {
+  runZonedExperimental(() => compilerMain(options), onError: (exception) {
     try {
       print('Internal error: $exception');
     } catch (ignored) {
diff --git a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
index ca73463..3b688f9 100644
--- a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
@@ -21,6 +21,11 @@
 
   void reportError(Spannable node, MessageKind errorCode, [Map arguments]);
 
+  // TODO(johnniwinther): Rename to [reportWarning] when
+  // [Compiler.reportWarning] has been removed.
+  void reportWarningCode(Spannable node, MessageKind errorCode,
+                         [Map arguments = const {}]);
+
   void reportInfo(Spannable node, MessageKind errorCode, [Map arguments]);
 
   // TODO(ahe): We should not expose this here.  Perhaps a
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index bacfc87..fda82a7 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -674,15 +674,31 @@
     importers[element] =
         importers.putIfAbsent(element, () => const Link<Import>())
         .prepend(import);
-    Element existing = importScope[element.name];
-    if (existing != null) {
-      // TODO(johnniwinther): Provide access to the import tags from which
-      // the elements came.
-      importScope[element.name] = new AmbiguousElementX(
-          MessageKind.DUPLICATE_IMPORT, {'name': element.name},
-          this, existing, element);
-    } else {
-      importScope[element.name] = element;
+    SourceString name = element.name;
+    Element existing = importScope.putIfAbsent(name, () => element);
+    if (existing != element) {
+      if (existing.getLibrary().isPlatformLibrary &&
+          !element.getLibrary().isPlatformLibrary) {
+        // [existing] is implicitly hidden.
+        importScope[name] = element;
+        listener.reportWarningCode(import, MessageKind.HIDDEN_IMPORT,
+            {'name': name,
+             'hiddenUri': existing.getLibrary().canonicalUri,
+             'hidingUri': element.getLibrary().canonicalUri});
+      } else if (!existing.getLibrary().isPlatformLibrary &&
+                 element.getLibrary().isPlatformLibrary) {
+        // [element] is implicitly hidden.
+        listener.reportWarningCode(import, MessageKind.HIDDEN_IMPORT,
+            {'name': name,
+             'hiddenUri': element.getLibrary().canonicalUri,
+             'hidingUri': existing.getLibrary().canonicalUri});
+      } else {
+        // TODO(johnniwinther): Provide access to the import tags from which
+        // the elements came.
+        importScope[name] = new AmbiguousElementX(
+            MessageKind.DUPLICATE_IMPORT, {'name': name},
+            this, existing, element);
+      }
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 622c20a..2324884a4 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -89,6 +89,8 @@
            ItemCompilationContext itemCompilationContextCreator())
     : this.itemCompilationContextCreator = itemCompilationContextCreator;
 
+  Queue<WorkItem> get queue;
+
   /// Returns [:true:] if this enqueuer is the resolution enqueuer.
   bool get isResolutionQueue => false;
 
@@ -529,7 +531,15 @@
     universe.closurizedGenericMembers.add(element);
   }
 
-  void forEach(f(WorkItem work));
+  void forEach(f(WorkItem work)) {
+    do {
+      while (!queue.isEmpty) {
+        // TODO(johnniwinther): Find an optimal process order.
+        f(queue.removeLast());
+      }
+      compiler.backend.onQueueEmpty(this);
+    } while (!queue.isEmpty);
+  }
 
   void forEachPostProcessTask(f(PostProcessTask work)) {}
 
@@ -661,13 +671,6 @@
     compiler.backend.enableNoSuchMethod(this);
   }
 
-  void forEach(f(WorkItem work)) {
-    while (!queue.isEmpty) {
-      // TODO(johnniwinther): Find an optimal process order for resolution.
-      f(queue.removeLast());
-    }
-  }
-
   /**
    * Adds an action to the post-processing queue.
    *
@@ -726,13 +729,6 @@
     queue.add(workItem);
   }
 
-  void forEach(f(WorkItem work)) {
-    while(!queue.isEmpty) {
-      // TODO(johnniwinther): Find an optimal process order for codegen.
-      f(queue.removeLast());
-    }
-  }
-
   void _logSpecificSummary(log(message)) {
     log('Compiled ${generatedCode.length} methods.');
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 35e7b10..703979d 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -414,6 +414,9 @@
           checkedModeHelpers,
           key: (helper) => helper.name.slowToString());
 
+  /// Number of methods compiled before considering reflection.
+  int preMirrorsMethodCount = 0;
+
   JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
       : namer = determineNamer(compiler),
         oneShotInterceptors = new Map<String, Selector>(),
@@ -435,17 +438,34 @@
         new Namer(compiler);
   }
 
-  bool canBeUsedForGlobalOptimizations(Element element) {
+  bool usedByBackend(Element element) {
     if (element.isParameter()
         || element.isFieldParameter()
         || element.isField()) {
-      if (hasInsufficientMirrorsUsed && compiler.enabledInvokeOn) return false;
-      if (!canBeUsedForGlobalOptimizations(element.enclosingElement)) {
+      if (usedByBackend(element.enclosingElement)) return true;
+    }
+    return helpersUsed.contains(element.declaration);
+  }
+
+  bool invokedReflectively(Element element) {
+    if (element.isParameter() || element.isFieldParameter()) {
+      if (hasInsufficientMirrorsUsed && compiler.enabledInvokeOn) return true;
+      if (invokedReflectively(element.enclosingElement)) return true;
+    }
+
+    if (element.isField()) {
+      if (Elements.isStaticOrTopLevel(element)
+          && (element.modifiers.isFinal() || element.modifiers.isConst())) {
         return false;
       }
+      if (hasInsufficientMirrorsUsed && compiler.enabledInvokeOn) return true;
     }
-    element = element.declaration;
-    return !isNeededForReflection(element) && !helpersUsed.contains(element);
+
+    return isNeededForReflection(element.declaration);
+  }
+
+  bool canBeUsedForGlobalOptimizations(Element element) {
+    return !usedByBackend(element) && !invokedReflectively(element);
   }
 
   bool isInterceptorClass(ClassElement element) {
@@ -1216,6 +1236,28 @@
 
   void assembleProgram() {
     emitter.assembleProgram();
+    int totalMethodCount = generatedCode.length;
+    if (totalMethodCount != preMirrorsMethodCount) {
+      int mirrorCount = totalMethodCount - preMirrorsMethodCount;
+      double percentage = (mirrorCount / totalMethodCount) * 100;
+      compiler.reportHint(
+          compiler.mainApp, MessageKind.MIRROR_BLOAT,
+          {'count': mirrorCount,
+           'total': totalMethodCount,
+           'percentage': percentage.round()});
+      for (LibraryElement library in compiler.libraries.values) {
+        if (library.isInternalLibrary) continue;
+        for (LibraryTag tag in library.tags) {
+          Import importTag = tag.asImport();
+          if (importTag == null) continue;
+          LibraryElement importedLibrary = library.getLibraryFromTag(tag);
+          if (importedLibrary != compiler.mirrorsLibrary) continue;
+          compiler.withCurrentElement(library, () {
+            compiler.reportInfo(importTag, MessageKind.MIRROR_IMPORT);
+          });
+        }
+      }
+    }
   }
 
   Element getImplementationClass(Element element) {
@@ -1524,28 +1566,10 @@
     if (element == disableTreeShakingMarker) {
       compiler.disableTypeInferenceForMirrors = true;
       isTreeShakingDisabled = true;
-      enqueuer.enqueueEverything();
     } else if (element == preserveNamesMarker) {
-      if (mustPreserveNames) return;
       mustPreserveNames = true;
-      compiler.log('Preserving names.');
     } else if (element == preserveMetadataMarker) {
-      if (mustRetainMetadata) return;
-      compiler.log('Retaining metadata.');
       mustRetainMetadata = true;
-      compiler.libraries.values.forEach(retainMetadataOf);
-      for (Dependency dependency in metadataInstantiatedTypes) {
-        registerMetadataInstantiatedType(dependency.type, dependency.user);
-      }
-      metadataInstantiatedTypes.clear();
-      for (Element e in metadataStaticUse) {
-        registerMetadataStaticUse(e);
-      }
-      metadataStaticUse.clear();
-      for (Element e in metadataGetOfStaticFunction) {
-        registerMetadataGetOfStaticFunction(e);
-      }
-      metadataGetOfStaticFunction.clear();
     }
   }
 
@@ -1734,6 +1758,35 @@
         && mask.satisfies(compiler.typedDataClass, compiler)
         && mask.satisfies(jsIndexingBehaviorInterface, compiler);
   }
+
+  /// Called when [enqueuer] is empty, but before it is closed.
+  void onQueueEmpty(Enqueuer enqueuer) {
+    if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) {
+      preMirrorsMethodCount = generatedCode.length;
+    }
+
+    if (isTreeShakingDisabled) enqueuer.enqueueEverything();
+
+    if (mustPreserveNames) compiler.log('Preserving names.');
+
+    if (mustRetainMetadata) {
+      compiler.log('Retaining metadata.');
+
+      compiler.libraries.values.forEach(retainMetadataOf);
+      for (Dependency dependency in metadataInstantiatedTypes) {
+        registerMetadataInstantiatedType(dependency.type, dependency.user);
+      }
+      metadataInstantiatedTypes.clear();
+      for (Element e in metadataStaticUse) {
+        registerMetadataStaticUse(e);
+      }
+      metadataStaticUse.clear();
+      for (Element e in metadataGetOfStaticFunction) {
+        registerMetadataGetOfStaticFunction(e);
+      }
+      metadataGetOfStaticFunction.clear();
+    }
+  }
 }
 
 /// Records that [type] is used by [user.element].
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 8804282..ba51d89 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -2568,6 +2568,7 @@
 
       List<String> parameters = <String>[];
       List<jsAst.Expression> arguments = <jsAst.Expression>[];
+      arguments.add(js('this')[fieldNames[0]]);
       if (inInterceptor) {
         arguments.add(js('this')[fieldNames[2]]);
       }
@@ -2580,7 +2581,7 @@
       jsAst.Expression fun = js.fun(
           parameters,
           js.return_(
-              js('this')[fieldNames[0]][js('this')[fieldNames[1]]](arguments)));
+              js('this')[fieldNames[1]]['call'](arguments)));
       boundClosureBuilder.addProperty(invocationName, fun);
 
       addParameterStubs(callElement, boundClosureBuilder.addProperty);
@@ -2621,7 +2622,10 @@
     List<String> parameters = <String>[];
     List<jsAst.Expression> arguments = <jsAst.Expression>[];
     arguments.add(js('this'));
-    arguments.add(js.string(targetName));
+    jsAst.PropertyAccess method =
+        backend.namer.elementAccess(classElement)['prototype'][targetName];
+
+    arguments.add(method);
     if (inInterceptor) {
       String receiverArg = fieldNames[2];
       parameters.add(receiverArg);
@@ -2630,6 +2634,7 @@
       // Put null in the intercepted receiver field.
       arguments.add(new jsAst.LiteralNull());
     }
+    arguments.add(js.string(targetName));
 
     jsAst.Expression getterFunction = js.fun(
         parameters, js.return_(js(closureClass).newWith(arguments)));
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 3c515a1..9ac6cfd 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -281,7 +281,7 @@
 
     // TODO(rnystrom): Remove .toList() here if #11523 is fixed.
     return Future.forEach(library.tags.reverse().toList(), (LibraryTag tag) {
-      compiler.withCurrentElement(library, () {
+      return compiler.withCurrentElement(library, () {
         if (tag.isImport) {
           Import import = tag;
           tagState = checkTag(TagState.IMPORT_OR_EXPORT, import);
@@ -565,7 +565,7 @@
       });
     } else {
       importedLibrary.forEachExport((Element element) {
-        compiler.withCurrentElement(element, () {
+        compiler.withCurrentElement(importingLibrary, () {
           if (combinatorFilter.exclude(element)) return;
           importingLibrary.addImport(element, import, compiler);
         });
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 553f9de..9643027 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -1151,6 +1151,7 @@
     builder.push(new HForeign.statement(
         new js.LiteralStatement(jsCode.dartString.slowToString()),
         <HInstruction>[],
-        new SideEffects()));
+        new SideEffects(),
+        null));
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index dcfbc59..63e7da7 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -4,6 +4,17 @@
 
 part of scanner;
 
+class FormalParameterType {
+  final String type;
+  const FormalParameterType(this.type);
+  bool get isRequired => this == REQUIRED;
+  bool get isPositional => this == POSITIONAL;
+  bool get isNamed => this == NAMED;
+  static final REQUIRED = const FormalParameterType('required');
+  static final POSITIONAL = const FormalParameterType('positional');
+  static final NAMED = const FormalParameterType('named');
+}
+
 /**
  * An event generating parser of Dart programs. This parser expects
  * all tokens in a linked list (aka a token stream).
@@ -306,13 +317,13 @@
         token = parseOptionalFormalParameters(token, true);
         break;
       }
-      token = parseFormalParameter(token);
+      token = parseFormalParameter(token, FormalParameterType.REQUIRED);
     } while (optional(',', token));
     listener.endFormalParameters(parameterCount, begin, token);
     return expect(')', token);
   }
 
-  Token parseFormalParameter(Token token) {
+  Token parseFormalParameter(Token token, FormalParameterType type) {
     listener.beginFormalParameter(token);
     token = parseModifiers(token);
     // TODO(ahe): Validate that there are formal parameters if void.
@@ -335,6 +346,15 @@
       Token equal = token;
       token = parseExpression(token.next);
       listener.handleValuedFormalParameter(equal, token);
+      if (type.isRequired) {
+        listener.reportError(equal,
+            MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT);
+      } else if (type.isNamed && identical('=', value)) {
+        listener.reportError(equal, MessageKind.NAMED_PARAMETER_WITH_EQUALS);
+      } else if (type.isPositional && identical(':', value)) {
+        listener.reportError(equal,
+            MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS);
+      }
     }
     listener.endFormalParameter(thisKeyword);
     return token;
@@ -347,7 +367,9 @@
     int parameterCount = 0;
     do {
       token = token.next;
-      token = parseFormalParameter(token);
+      var type = isNamed ? FormalParameterType.NAMED
+                         : FormalParameterType.POSITIONAL;
+      token = parseFormalParameter(token, type);
       ++parameterCount;
     } while (optional(',', token));
     listener.endOptionalFormalParameters(parameterCount, begin, token);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index d2a303d..4e50630 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -912,6 +912,14 @@
     }
   }
 
+  /// A stack of [DartType]s the have been seen during inlining of factory
+  /// constructors.  These types are preserved in [HInvokeStatic]s and
+  /// [HForeignNews] inside the inline code and registered during code
+  /// generation for these nodes.
+  // TODO(karlklose): consider removing this and keeping the (substituted)
+  // types of the type variables in an environment (like the [LocalsHandler]).
+  final List<DartType> currentInlinedInstantiations = <DartType>[];
+
   Compiler get compiler => builder.compiler;
   CodeEmitterTask get emitter => builder.emitter;
 
@@ -1220,7 +1228,8 @@
   bool tryInlineMethod(Element element,
                        Selector selector,
                        List<HInstruction> providedArguments,
-                       Node currentNode) {
+                       Node currentNode,
+                       [DartType instantiatedType]) {
     backend.registerStaticUse(element, compiler.enqueuer.codegen);
 
     // Ensure that [element] is an implementation element.
@@ -1319,9 +1328,13 @@
           HInstruction argument = localsHandler.readLocal(parameter);
           potentiallyCheckType(argument, parameter.computeType(compiler));
         });
-        element.isGenerativeConstructor()
-            ? buildFactory(element)
-            : functionExpression.body.accept(this);
+        addInlinedInstantiation(instantiatedType);
+        if (element.isGenerativeConstructor()) {
+          buildFactory(element);
+        } else {
+          functionExpression.body.accept(this);
+        }
+        removeInlinedInstantiation(instantiatedType);
       });
       leaveInlinedMethod(state);
     }
@@ -1338,6 +1351,18 @@
     return false;
   }
 
+  addInlinedInstantiation(DartType type) {
+    if (type != null) {
+      currentInlinedInstantiations.add(type);
+    }
+  }
+
+  removeInlinedInstantiation(DartType type) {
+    if (type != null) {
+      currentInlinedInstantiations.removeLast();
+    }
+  }
+
   inlinedFrom(Element element, f()) {
     assert(element is FunctionElement || element is VariableElement);
     return compiler.withCurrentElement(element, () {
@@ -1389,10 +1414,14 @@
         }
       }
 
-      inlinedFrom(callee, () {
-        buildFieldInitializers(callee.enclosingElement.implementation,
+      // For redirecting constructors, the fields have already been
+      // initialized by the caller.
+      if (callee.getEnclosingClass() != caller.getEnclosingClass()) {
+        inlinedFrom(callee, () {
+          buildFieldInitializers(callee.enclosingElement.implementation,
                                fieldValues);
-      });
+        });
+      }
 
       int index = 0;
       FunctionSignature params = callee.computeSignature(compiler);
@@ -1627,11 +1656,17 @@
 
     InterfaceType type = classElement.computeType(compiler);
     HType ssaType = new HType.nonNullExact(type, compiler);
+    List<DartType> instantiatedTypes;
+    addInlinedInstantiation(type);
+    if (!currentInlinedInstantiations.isEmpty) {
+      instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
+    }
     HForeignNew newObject = new HForeignNew(classElement,
                                             ssaType,
-                                            constructorArguments);
+                                            constructorArguments,
+                                            instantiatedTypes);
     add(newObject);
-
+    removeInlinedInstantiation(type);
     // Create the runtime type information, if needed.
     if (backend.classNeedsRti(classElement)) {
       List<HInstruction> rtiInputs = <HInstruction>[];
@@ -2592,6 +2627,9 @@
       if (value != null) {
         HInstruction instruction = graph.addConstant(value, compiler);
         stack.add(instruction);
+        // The inferrer may have found a better type than the constant
+        // handler in the case of lists, because the constant handler
+        // does not look at elements in the list.
         HType type = new HType.inferredTypeForElement(element, compiler);
         if (!type.isUnknown()) instruction.instructionType = type;
       } else if (element.isField() && isLazilyInitialized(element)) {
@@ -2699,10 +2737,10 @@
     return interceptor;
   }
 
-  HForeign createForeign(String code,
+  HForeign createForeign(js.Expression code,
                          HType type,
                          List<HInstruction> inputs) {
-    return new HForeign(js.js.parseForeignJS(code), type, inputs);
+    return new HForeign(code, type, inputs);
   }
 
   HInstruction getRuntimeTypeInfo(HInstruction target) {
@@ -2734,8 +2772,9 @@
         }));
       }
       String template = '[${templates.join(', ')}]';
+      js.Expression code = js.js.parseForeignJS(template);
       HInstruction representation =
-        createForeign(template, backend.readableArrayType, inputs);
+        createForeign(code, backend.readableArrayType, inputs);
       return representation;
     }
   }
@@ -3419,7 +3458,8 @@
       inputs.add(addTypeVariableReference(variable));
     });
 
-    HInstruction result = createForeign(template, backend.stringType, inputs);
+    js.Expression code = js.js.parseForeignJS(template);
+    HInstruction result = createForeign(code, backend.stringType, inputs);
     add(result);
     return result;
   }
@@ -3457,10 +3497,11 @@
     pop();
   }
 
-  handleNewSend(NewExpression node, InterfaceType type) {
+  handleNewSend(NewExpression node) {
     Send send = node.send;
     bool isListConstructor = false;
-    computeType(element) {
+
+    HType computeType(element) {
       Element originalElement = elements[send];
       if (Elements.isFixedListConstructorCall(originalElement, send, compiler)
           || Elements.isFilledListConstructorCall(
@@ -3502,6 +3543,7 @@
     }
 
     bool isRedirected = functionElement.isRedirectingFactory;
+    InterfaceType type = elements.getType(node);
     DartType expectedType = type;
     if (isRedirected) {
       type = functionElement.computeTargetType(compiler, type);
@@ -3529,19 +3571,16 @@
         inputs.add(analyzeTypeArgument(argument));
         typeVariable = typeVariable.tail;
       });
-      // Also add null to non-provided type variables to call the
-      // constructor with the right number of arguments.
-      while (!typeVariable.isEmpty) {
-        inputs.add(graph.addConstantNull(compiler));
-        typeVariable = typeVariable.tail;
-      }
+      assert(typeVariable.isEmpty);
     }
 
     if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
       compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
     }
     HType elementType = computeType(constructor);
+    addInlinedInstantiation(expectedType);
     pushInvokeStatic(node, constructor, inputs, elementType);
+    removeInlinedInstantiation(expectedType);
     HInstruction newInstance = stack.last;
 
     // The List constructor forwards to a Dart static method that does
@@ -3761,10 +3800,7 @@
         compiler.enqueuer.codegen.registerConstSymbol(nameString, elements);
       }
     } else {
-      DartType type = elements.getType(node);
-      // TODO(karlklose): move this type registration to the codegen.
-      compiler.codegenWorld.instantiatedTypes.add(type);
-      handleNewSend(node, type);
+      handleNewSend(node);
     }
   }
 
@@ -3858,8 +3894,12 @@
     }
     // TODO(5346): Try to avoid the need for calling [declaration] before
     // creating an [HInvokeStatic].
-    HInstruction instruction =
+    HInvokeStatic instruction =
         new HInvokeStatic(element.declaration, arguments, type);
+    if (!currentInlinedInstantiations.isEmpty) {
+      instruction.instantiatedTypes = new List<DartType>.from(
+          currentInlinedInstantiations);
+    }
     instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
     if (location == null) {
       push(instruction);
@@ -4142,8 +4182,38 @@
     }
     HInstruction value;
     if (node.isRedirectingFactoryBody) {
-      // TODO(ahe): This is only for reflection, and it is not correct yet.
-      value = graph.addConstantNull(compiler);
+      FunctionElement element = elements[node.expression];
+      FunctionElement function = currentElement;
+      List<HInstruction> inputs = <HInstruction>[];
+      FunctionSignature calleeSignature = element.functionSignature;
+      FunctionSignature callerSignature = function.functionSignature;
+      callerSignature.forEachRequiredParameter((Element element) {
+        inputs.add(localsHandler.readLocal(element));
+      });
+      List<Element> calleeOptionals =
+          calleeSignature.orderedOptionalParameters;
+      List<Element> callerOptionals =
+          callerSignature.orderedOptionalParameters;
+      int i = 0;
+      for (; i < callerOptionals.length; i++) {
+        inputs.add(localsHandler.readLocal(callerOptionals[i]));
+      }
+      for (; i < calleeOptionals.length; i++) {
+        inputs.add(handleConstantForOptionalParameter(calleeOptionals[i]));
+      }
+
+      if (backend.classNeedsRti(element.getEnclosingClass())) {
+        ClassElement cls = function.getEnclosingClass();
+        Link<DartType> typeVariable = cls.typeVariables;
+        InterfaceType type = elements.getType(node.expression);
+        type.typeArguments.forEach((DartType argument) {
+          inputs.add(analyzeTypeArgument(argument));
+          typeVariable = typeVariable.tail;
+        });
+        assert(typeVariable.isEmpty);
+      }
+      pushInvokeStatic(node, element, inputs);
+      value = pop();
     } else if (node.expression == null) {
       value = graph.addConstantNull(compiler);
     } else {
@@ -4655,7 +4725,9 @@
       // If the switch statement has no default case, surround the loop with
       // a test of the target.
       void buildCondition() {
-        push(createForeign('#', HType.BOOLEAN,
+        js.Expression code = js.js.parseForeignJS('#');
+        push(createForeign(code,
+                           HType.BOOLEAN,
                            [localsHandler.readLocal(switchTarget)]));
       }
       handleIf(node, buildCondition, buildLoop, () => {});
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 6f1fe66..f072081 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -299,8 +299,8 @@
     new SsaInstructionMerger(generateAtUseSite, compiler).visitGraph(graph);
     new SsaConditionMerger(
         generateAtUseSite, controlFlowOperators).visitGraph(graph);
-    SsaLiveIntervalBuilder intervalBuilder =
-        new SsaLiveIntervalBuilder(compiler, generateAtUseSite);
+    SsaLiveIntervalBuilder intervalBuilder = new SsaLiveIntervalBuilder(
+        compiler, generateAtUseSite, controlFlowOperators);
     intervalBuilder.visitGraph(graph);
     SsaVariableAllocator allocator = new SsaVariableAllocator(
         compiler,
@@ -1628,12 +1628,17 @@
 
   visitInvokeStatic(HInvokeStatic node) {
     Element element = node.element;
-    world.registerStaticUse(element);
     ClassElement cls = element.getEnclosingClass();
-    if (element.isGenerativeConstructor()
-        || (element.isFactoryConstructor() && cls == compiler.listClass)) {
-      world.registerInstantiatedClass(cls, work.resolutionTree);
+    List<DartType> instantiatedTypes = node.instantiatedTypes;
+
+    world.registerStaticUse(element);
+
+    if (instantiatedTypes != null && !instantiatedTypes.isEmpty) {
+      instantiatedTypes.forEach((type) {
+        world.registerInstantiatedType(type, work.resolutionTree);
+      });
     }
+
     push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
     push(new js.Call(pop(), visitArguments(node.inputs, start: 0)), node);
   }
@@ -1641,7 +1646,7 @@
   visitInvokeSuper(HInvokeSuper node) {
     Element superMethod = node.element;
     world.registerStaticUse(superMethod);
-    Element superClass = superMethod.getEnclosingClass();
+    ClassElement superClass = superMethod.getEnclosingClass();
     if (superMethod.kind == ElementKind.FIELD) {
       String fieldName = node.caller.isShadowedByField(superMethod)
           ? backend.namer.shadowedFieldName(superMethod)
@@ -1656,13 +1661,21 @@
         push(access, node);
       }
     } else {
-      String methodName = backend.namer.getNameOfInstanceMember(superMethod);
-      String className = backend.namer.isolateAccess(superClass);
-      js.VariableUse classReference = new js.VariableUse(className);
-      js.PropertyAccess prototype =
-          new js.PropertyAccess.field(classReference, "prototype");
+      Selector selector = node.selector;
+      String methodName;
+      if (selector.isGetter()) {
+        // If the selector we need to register a typed getter to the
+        // [world]. The emitter needs to know if it needs to emit a
+        // bound closure for a method.
+        TypeMask receiverType = new TypeMask.nonNullExact(superClass.rawType);
+        selector = new TypedSelector(receiverType, selector);
+        world.registerDynamicGetter(selector);
+        methodName = backend.namer.invocationName(selector);
+      } else {
+        methodName = backend.namer.getNameOfInstanceMember(superMethod);
+      }
       js.PropertyAccess method =
-          new js.PropertyAccess.field(prototype, methodName);
+          backend.namer.elementAccess(superClass)['prototype'][methodName];
       push(jsPropertyCall(
           method, "call", visitArguments(node.inputs, start: 0)), node);
     }
@@ -1721,12 +1734,14 @@
     assignVariable(variableNames.getName(node.receiver), pop());
   }
 
-  void registerForeignType(HType type) {
-    if (type.isUnknown()) return;
-    TypeMask mask = type.computeMask(compiler);
-    for (ClassElement cls in mask.containedClasses(compiler)) {
-      world.registerInstantiatedClass(cls, work.resolutionTree);
-    }
+  void registerForeignTypes(HForeign node) {
+    native.NativeBehavior nativeBehavior = node.nativeBehavior;
+    if (nativeBehavior == null) return;
+    nativeBehavior.typesReturned.forEach((type) {
+      if (type is DartType) {
+        world.registerInstantiatedType(type, work.resolutionTree);
+      }
+    });
   }
 
   visitForeign(HForeign node) {
@@ -1751,8 +1766,8 @@
       }
     }
 
-    registerForeignType(node.instructionType);
     // TODO(sra): Tell world.nativeEnqueuer about the types created here.
+    registerForeignTypes(node);
   }
 
   visitForeignNew(HForeignNew node) {
@@ -1761,7 +1776,13 @@
     // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it
     // as if it was a string.
     push(new js.New(new js.VariableUse(jsClassReference), arguments), node);
-    registerForeignType(node.instructionType);
+    registerForeignTypes(node);
+    if (node.instantiatedTypes == null) {
+      return;
+    }
+    node.instantiatedTypes.forEach((type) {
+      world.registerInstantiatedType(type, work.resolutionTree);
+    });
   }
 
   js.Expression newLiteralBool(bool value) {
@@ -1978,23 +1999,35 @@
       js.Statement thenBody = new js.Block.empty();
       js.Block oldContainer = currentContainer;
       currentContainer = thenBody;
-      generateThrowWithHelper('ioore', node.index);
+      generateThrowWithHelper('ioore', [node.array, node.index]);
       currentContainer = oldContainer;
       thenBody = unwrapStatement(thenBody);
       pushStatement(new js.If.noElse(underOver, thenBody), node);
     } else {
-      generateThrowWithHelper('ioore', node.index);
+      generateThrowWithHelper('ioore', [node.array, node.index]);
     }
   }
 
-  void generateThrowWithHelper(String helperName, HInstruction argument) {
+  void generateThrowWithHelper(String helperName, argument) {
     Element helper = compiler.findHelper(new SourceString(helperName));
     world.registerStaticUse(helper);
     js.VariableUse jsHelper =
         new js.VariableUse(backend.namer.isolateAccess(helper));
-    use(argument);
-    js.Call value = new js.Call(jsHelper, [pop()]);
-    attachLocation(value, argument);
+    List arguments = [];
+    var location;
+    if (argument is List) {
+      location = argument[0];
+      argument.forEach((instruction) {
+        use(instruction);
+        arguments.add(pop());
+      });
+    } else {
+      location = argument;
+      use(argument);
+      arguments.add(pop());
+    }
+    js.Call value = new js.Call(jsHelper, arguments);
+    attachLocation(value, location);
     // BUG(4906): Using throw here adds to the size of the generated code
     // but it has the advantage of explicitly telling the JS engine that
     // this code path will terminate abruptly. Needs more work.
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index cc36e72..88ce60b 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -264,7 +264,7 @@
     // they have side effects.
     HInstruction instruction;
     if (selector.isGetter()) {
-      instruction= new HInvokeDynamicGetter(
+      instruction = new HInvokeDynamicGetter(
           selector,
           node.element,
           <HInstruction>[constant, node.inputs[1]],
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index c7770c8..15d48d1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -887,6 +887,7 @@
 
   Selector get selector => null;
   HInstruction getDartReceiver(Compiler compiler) => null;
+  bool onlyThrowsNSM() => false;
 
   bool isInBasicBlock() => block != null;
 
@@ -1250,12 +1251,14 @@
    */
   int staticChecks = FULL_CHECK;
 
-  HBoundsCheck(length, index) : super(<HInstruction>[length, index]) {
+  HBoundsCheck(length, index, array)
+      : super(<HInstruction>[length, index, array]) {
     instructionType = HType.INTEGER;
   }
 
   HInstruction get length => inputs[1];
   HInstruction get index => inputs[0];
+  HInstruction get array => inputs[2];
   bool isControlFlow() => true;
 
   accept(HVisitor visitor) => visitor.visitBoundsCheck(this);
@@ -1406,6 +1409,13 @@
 
 class HInvokeStatic extends HInvoke {
   final Element element;
+
+  /// If this instruction is a call to a constructor, [instantiatedTypes]
+  /// contains the type(s) used in the (Dart) `New` expression(s).
+  /// The [instructionType] of this node is not enough, because we also need
+  /// the type arguments.  See also [SsaBuilder.currentInlinedInstantiations].
+  List<DartType> instantiatedTypes;
+
   /** The first input must be the target. */
   HInvokeStatic(this.element, inputs, HType type) : super(inputs) {
     instructionType = type;
@@ -1483,6 +1493,9 @@
 
   bool canThrow() => receiver.canBeNull();
 
+  HInstruction getDartReceiver(Compiler compiler) => receiver;
+  bool onlyThrowsNSM() => true;
+
   accept(HVisitor visitor) => visitor.visitFieldGet(this);
 
   int typeCode() => HInstruction.FIELD_GET_TYPECODE;
@@ -1502,6 +1515,9 @@
 
   bool canThrow() => receiver.canBeNull();
 
+  HInstruction getDartReceiver(Compiler compiler) => receiver;
+  bool onlyThrowsNSM() => true;
+
   HInstruction get value => inputs[1];
   accept(HVisitor visitor) => visitor.visitFieldSet(this);
 
@@ -1534,20 +1550,27 @@
 class HForeign extends HInstruction {
   final js.Node codeAst;
   final bool isStatement;
+  final native.NativeBehavior nativeBehavior;
 
   HForeign(this.codeAst,
            HType type,
            List<HInstruction> inputs,
            {this.isStatement: false,
-            SideEffects effects})
-      : super(inputs) {
+            SideEffects effects,
+            native.NativeBehavior nativeBehavior})
+      : this.nativeBehavior = nativeBehavior, super(inputs) {
+    if (effects == null && nativeBehavior != null) {
+      effects = nativeBehavior.sideEffects;
+    }
     if (effects != null) sideEffects.add(effects);
     instructionType = type;
   }
 
-  HForeign.statement(codeAst, List<HInstruction> inputs, SideEffects effects)
+  HForeign.statement(codeAst, List<HInstruction> inputs,
+                     SideEffects effects,
+                     native.NativeBehavior nativeBehavior)
       : this(codeAst, HType.UNKNOWN, inputs, isStatement: true,
-             effects: effects);
+             effects: effects, nativeBehavior: nativeBehavior);
 
   accept(HVisitor visitor) => visitor.visitForeign(this);
 
@@ -1559,8 +1582,17 @@
 
 class HForeignNew extends HForeign {
   ClassElement element;
-  HForeignNew(this.element, HType type, List<HInstruction> inputs)
+
+  /// If this field is not `null`, this call is from an inlined constructor and
+  /// we have to register the instantiated type in the code generator.
+  /// The [instructionType] of this node is not enough, because we also need
+  /// the type arguments.  See also [SsaBuilder.currentInlinedInstantiations].
+  List<DartType> instantiatedTypes;
+
+  HForeignNew(this.element, HType type, List<HInstruction> inputs,
+              [this.instantiatedTypes])
       : super(null, type, inputs);
+
   accept(HVisitor visitor) => visitor.visitForeignNew(this);
 }
 
@@ -2178,6 +2210,9 @@
   HInstruction get receiver => inputs[0];
   HInstruction get index => inputs[1];
 
+  HInstruction getDartReceiver(Compiler compiler) => receiver;
+  bool onlyThrowsNSM() => true;
+
   int typeCode() => HInstruction.INDEX_TYPECODE;
   bool typeEquals(HInstruction other) => other is HIndex;
   bool dataEquals(HIndex other) => true;
@@ -2203,6 +2238,9 @@
   HInstruction get receiver => inputs[0];
   HInstruction get index => inputs[1];
   HInstruction get value => inputs[2];
+
+  HInstruction getDartReceiver(Compiler compiler) => receiver;
+  bool onlyThrowsNSM() => true;
 }
 
 class HIs extends HInstruction {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 463e198..333bd7e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -299,13 +299,17 @@
         }
       } else if (input.isString(compiler)) {
         if (selector.applies(backend.jsStringSplit, compiler)) {
-          if (node.inputs[2].isString(compiler)) {
+          HInstruction argument = node.inputs[2];
+          if (argument.isString(compiler) && !argument.canBeNull()) {
             target = backend.jsStringSplit;
           }
         } else if (selector.applies(backend.jsStringOperatorAdd, compiler)) {
           // `operator+` is turned into a JavaScript '+' so we need to
-          // make sure the receiver is not null.
-          if (node.inputs[2].isString(compiler) && !input.canBeNull()) {
+          // make sure the receiver and the argument are not null.
+          HInstruction argument = node.inputs[2];
+          if (argument.isString(compiler)
+              && !argument.canBeNull()
+              && !input.canBeNull()) {
             target = backend.jsStringOperatorAdd;
           }
         } else if (selector.applies(backend.jsStringToString, compiler)
@@ -877,7 +881,7 @@
     length.instructionType = HType.INTEGER;
     indexNode.block.addBefore(indexNode, length);
 
-    HBoundsCheck check = new HBoundsCheck(indexArgument, length);
+    HBoundsCheck check = new HBoundsCheck(indexArgument, length, array);
     indexNode.block.addBefore(indexNode, check);
     // If the index input to the bounds check was not known to be an integer
     // then we replace its uses with the bounds check, which is known to be an
@@ -930,10 +934,34 @@
         : zapInstructionCache;
   }
 
+  /// Returns whether the next throwing instruction that may have side
+  /// effects after [instruction], throws [NoSuchMethodError] on the
+  /// same receiver of [instruction].
+  bool hasFollowingThrowingNSM(HInstruction instruction) {
+    HInstruction receiver = instruction.getDartReceiver(compiler);
+    HInstruction current = instruction.next;
+    do {
+      if ((current.getDartReceiver(compiler) == receiver)
+          && current.canThrow()) {
+        return true;
+      }
+      if (current.canThrow() || current.sideEffects.hasSideEffects()) {
+        return false;
+      }
+      current = current.next;
+    } while (current != null);
+    return false;
+  }
+
   bool isDeadCode(HInstruction instruction) {
-    return !instruction.sideEffects.hasSideEffects()
-           && !instruction.canThrow()
-           && instruction.usedBy.isEmpty
+    if (!instruction.usedBy.isEmpty) return false;
+    if (instruction.sideEffects.hasSideEffects()) return false;
+    if (instruction.canThrow()
+        && instruction.onlyThrowsNSM()
+        && hasFollowingThrowingNSM(instruction)) {
+      return true;
+    }
+    return !instruction.canThrow()
            && instruction is !HTypeGuard
            && instruction is !HParameterValue
            && instruction is !HLocalSet;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
index 3df538d..f8c46f1a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
@@ -184,6 +184,7 @@
 class SsaLiveIntervalBuilder extends HBaseVisitor {
   final Compiler compiler;
   final Set<HInstruction> generateAtUseSite;
+  final Set<HInstruction> controlFlowOperators;
 
   /**
    * A counter to assign start and end ids to live ranges. The initial
@@ -203,7 +204,8 @@
    */
   final Map<HInstruction, LiveInterval> liveIntervals;
 
-  SsaLiveIntervalBuilder(this.compiler, this.generateAtUseSite)
+  SsaLiveIntervalBuilder(
+      this.compiler, this.generateAtUseSite, this.controlFlowOperators)
     : liveInstructions = new Map<HBasicBlock, LiveEnvironment>(),
       liveIntervals = new Map<HInstruction, LiveInterval>();
 
@@ -263,6 +265,19 @@
     LiveEnvironment environment =
         new LiveEnvironment(liveIntervals, instructionId);
 
+    // If the control flow instruction in this block will actually be
+    // inlined in the codegen in the join block, we need to make
+    // whatever is used by that control flow instruction as live in
+    // the join block.
+    if (controlFlowOperators.contains(block.last)) {
+      HIf ifInstruction = block.last;
+      HBasicBlock joinBlock = ifInstruction.joinBlock;
+      if (generateAtUseSite.contains(joinBlock.phis.first)) {
+        markInputsAsLiveInEnvironment(
+            ifInstruction, liveInstructions[joinBlock]);
+      }
+    }
+
     // Add to the environment the liveIn of its successor, as well as
     // the inputs of the phis of the successor that flow from this block.
     for (int i = 0; i < block.successors.length; i++) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart b/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
index 0abae5d..3737a48 100644
--- a/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
@@ -498,29 +498,6 @@
     return types.growableListType;
   }
 
-  // TODO(ngeoffray): Try to move the following two methods in
-  // [InferrerVisitor].
-  TypeMask visitCascadeReceiver(CascadeReceiver node) {
-    return visit(node.expression);
-  }
-
-  TypeMask visitCascade(Cascade node) {
-    Send send = node.expression;
-    TypeMask result;
-    bool isReceiver = visitAndCatchEscaping(() {
-      result = visit(send.receiver);
-    });
-    if (send.asSendSet() != null) {
-      handleSendSet(send, isReceiver);
-    } else {
-      handleDynamicSend(send, isReceiver);
-    }
-    if (isReceiver) {
-      escaping = true;
-    }
-    return result;
-  }
-
   TypeMask visitSendSet(SendSet node) {
     bool isReceiver = visitAndCatchEscaping(() {
       visit(node.receiver);
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index 6079d4b..4ff9f72 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -2168,8 +2168,7 @@
     } else if (Elements.isInstanceSend(node, elements)) {
       return visitDynamicSend(node);
     } else if (Elements.isStaticOrTopLevelFunction(element)) {
-      handleStaticSend(node, selector, element, null);
-      return types.functionType;
+      return handleStaticSend(node, selector, element, null);
     } else if (Elements.isErroneousElement(element)) {
       return types.dynamicType;
     } else if (Elements.isLocal(element)) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
index 0430004..730153d 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
@@ -259,17 +259,34 @@
     return null;
   }
 
+  TypeMask potentiallyNarrowType(TypeMask mask,
+                                 TypeGraphInferrerEngine inferrer) {
+    Compiler compiler = inferrer.compiler;
+    if (!compiler.trustTypeAnnotations && !compiler.enableTypeAssertions) {
+      return mask;
+    }
+    if (element.isGenerativeConstructor() || element.isSetter()) return mask;
+    var type = element.computeType(compiler);
+    if (element.isFunction()
+        || element.isGetter()
+        || element.isFactoryConstructor()) {
+      type = type.returnType;
+    }
+    return new TypeMaskSystem(compiler).narrowType(mask, type);
+  }
+
   TypeMask refine(TypeGraphInferrerEngine inferrer) {
     TypeMask special = handleSpecialCases(inferrer);
-    if (special != null) return special;
-    return inferrer.types.computeTypeMask(assignments);
+    if (special != null) return potentiallyNarrowType(special, inferrer);
+    return potentiallyNarrowType(
+        inferrer.types.computeTypeMask(assignments), inferrer);
   }
 
   TypeMask refineOptimistic(TypeGraphInferrerEngine inferrer) {
     TypeMask special = handleSpecialCases(inferrer);
-    if (special != null) return special;
-    return inferrer.types.computeTypeMask(
-        assignments.where((e) => e.isConcrete));
+    if (special != null) return potentiallyNarrowType(special, inferrer);
+    return potentiallyNarrowType(inferrer.types.computeTypeMask(
+        assignments.where((e) => e.isConcrete)), inferrer);
   }
 
   String toString() => 'Element $element';
@@ -330,8 +347,21 @@
         this, calledElement, arguments, selector, remove: false, init: true);
   }
 
+  bool get isSynthesized {
+    // Some calls do not have a corresponding node, for example
+    // fowarding factory constructors, or synthesized super
+    // constructor calls. We synthesize these calls but do
+    // not create a selector for them.
+    return selector == null;
+  }
+
   TypeMask refine(TypeGraphInferrerEngine inferrer) {
-    return inferrer.types.getInferredTypeOf(calledElement).type;
+    if (isSynthesized) {
+      assert(arguments != null);
+      return inferrer.types.getInferredTypeOf(calledElement).type;
+    } else {
+      return inferrer.typeOfElementWithSelector(calledElement, selector).type;
+    }
   }
 
   Iterable<Element> get callees => [calledElement.implementation];
@@ -542,8 +572,7 @@
  *   potential target of this dynamic call.
  *
  * - In checked mode, after a type annotation, we have more
- *   information on the type of an element (parameter, function,
- *   local). TODO(ngeoffray): Implement this.
+ *   information on the type of a local.
  */
 class NarrowTypeInformation extends TypeInformation {
   final TypeMask typeAnnotation;
@@ -1005,6 +1034,24 @@
     refine();
 
     compiler.log('Inferred $overallRefineCount types.');
+
+    if (compiler.enableTypeAssertions) {
+      // Undo the narrowing of parameters types. Parameters are being
+      // checked by the method, and we can therefore only trust their
+      // type after the checks. It is okay for the inferrer to rely on
+      // the type annotations, but the backend should has to
+      // insert the checks.
+      types.typeInformations.forEach((Element element,
+                                      ElementTypeInformation info) {
+        if (element.isParameter() || element.isFieldParameter()) {
+          if (info.abandonInferencing) {
+            info.type = types.dynamicType.type;
+          } else {
+            info.type = types.computeTypeMask(info.assignments);
+          }
+        }
+      });
+    }
   }
 
 
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index f8248d4..93a1a04 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -75,9 +75,15 @@
   /// Should describe how to fix the problem. Elided when using --terse option.
   final String howToFix;
 
-  /// Examples will be checked by
-  /// tests/compiler/dart2js/message_kind_test.dart.
-  final List<String> examples;
+  /**
+   *  Examples will be checked by
+   *  tests/compiler/dart2js/message_kind_test.dart.
+   *
+   *  An example is either a String containing the example source code or a Map
+   *  from filenames to source code. In the latter case, the filename for the
+   *  main library code must be 'main.dart'.
+   */
+  final List examples;
 
   const MessageKind(this.template, {this.howToFix, this.examples});
 
@@ -188,6 +194,59 @@
       error: const MessageKind('Error: Duplicate import of "#{name}".'),
       warning: const MessageKind('Warning: Duplicate import of "#{name}".'));
 
+  static const MessageKind HIDDEN_IMPORT = const MessageKind(
+      "Warning: '#{name}' from library '#{hiddenUri}' by '#{name}' "
+      "from library '#{hidingUri}'.",
+      howToFix: "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
+      examples: const [
+          const {
+'main.dart':
+"""
+import 'dart:async'; // This imports a class Future.
+import 'future.dart';
+
+void main() {}""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}"""},
+
+          const {
+'main.dart':
+"""
+import 'future.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() {}""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}"""},
+
+          const {
+'main.dart':
+"""
+import 'export.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() {}""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}""",
+
+'export.dart':
+"""
+library export;
+
+export 'future.dart';"""}]);
+
   static const MessageKind DUPLICATE_EXPORT = const MessageKind(
       'Error: Duplicate export of "#{name}".');
 
@@ -429,9 +488,44 @@
   static const MessageKind CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
       'Error: Cannot instantiate typedef "#{typedefName}".');
 
+  static const MessageKind REQUIRED_PARAMETER_WITH_DEFAULT = const MessageKind(
+      "Error: Non-optional parameters can't have a default value.",
+      howToFix:
+        "Try removing the default value or making the parameter optional.",
+      examples: const ["""
+main() {
+  foo(a: 1) => print(a);
+  foo(2);
+}""", """
+main() {
+  foo(a = 1) => print(a);
+  foo(2);
+}"""]);
+
+  static const MessageKind NAMED_PARAMETER_WITH_EQUALS = const MessageKind(
+      "Error: Named optional parameters can't use '=' to specify a default "
+      "value.",
+      howToFix: "Try replacing '=' with ':'.",
+      examples: const ["""
+main() {
+  foo({a = 1}) => print(a);
+  foo(a: 2);
+}"""]);
+
+  static const MessageKind POSITIONAL_PARAMETER_WITH_EQUALS = const MessageKind(
+      "Error: Positional optional parameters can't use ':' to specify a "
+      "default value.",
+      howToFix: "Try replacing ':' with '='.",
+      examples: const ["""
+main() {
+  foo([a: 1]) => print(a);
+  foo(2);
+}"""]);
+
   static const MessageKind TYPEDEF_FORMAL_WITH_DEFAULT = const MessageKind(
       "Error: A parameter of a typedef can't specify a default value.",
-      howToFix: "Remove the default value.",
+      howToFix:
+        "Try removing the default value or making the parameter optional.",
       examples: const ["""
 typedef void F([int arg = 0]);
 
@@ -902,6 +996,13 @@
       examples: const [
           "main();"]);
 
+  static const MessageKind MIRROR_BLOAT = const MessageKind(
+      "Hint: #{count} methods retained for use by dart:mirrors out of #{total}"
+      " total methods (#{percentage}%).");
+
+  static const MessageKind MIRROR_IMPORT = const MessageKind(
+      "Info: Import of 'dart:mirrors'.");
+
   static const MessageKind COMPILER_CRASHED = const MessageKind(
       'Error: The compiler crashed when compiling this element.');
 
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index d8fcff4a..7a6e620 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -604,15 +604,6 @@
     return spawn(name, null, false);
   }
 
-  static SendPort spawnDomFunction(void topLevelFunction()) {
-    final name = _getJSFunctionName(topLevelFunction);
-    if (name == null) {
-      throw new UnsupportedError(
-          "only top-level functions can be spawned.");
-    }
-    return spawn(name, null, true);
-  }
-
   // TODO(sigmund): clean up above, after we make the new API the default:
 
   static spawn(String functionName, String uri, bool isLight) {
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 0ce4ec6..f31a0b8 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -85,9 +85,9 @@
                                 argumentNames);
 }
 
-void throwInvalidReflectionError(Symbol memberName) {
-  throw new UnsupportedError('invalid reflective use of ${memberName}, '
-      'which is not included by a @MirrorsUsed annotation');
+void throwInvalidReflectionError(String memberName) {
+  throw new UnsupportedError("Can't use '$memberName' in reflection "
+      "because it is not included in a @MirrorsUsed annotation.");
 }
 
 bool hasReflectableProperty(var jsFunction) {
@@ -179,7 +179,7 @@
     var method = JS('var', '#[#]', receiver, name);
     if (JS('String', 'typeof #', method) == 'function') {
       if (!hasReflectableProperty(method)) {
-        throwInvalidReflectionError(memberName);
+        throwInvalidReflectionError(_symbol_dev.Symbol.getName(memberName));
       }
       return new CachedInvocation(method, isIntercepted, interceptor);
     } else {
@@ -775,9 +775,11 @@
  * Called by generated code to throw an index-out-of-range exception,
  * for example, if a bounds check fails in an optimized indexed
  * access.  This may also be called when the index is not an integer, in
- * which case it throws an illegal-argument exception instead, like [iae].
+ * which case it throws an illegal-argument exception instead, like
+ * [iae], or when the receiver is null.
  */
-ioore(index) {
+ioore(receiver, index) {
+  if (receiver == null) receiver.length; // Force a NoSuchMethodError.
   if (index is !int) iae(index);
   throw new RangeError.value(index);
 }
@@ -1495,12 +1497,15 @@
   // we need the interceptor when generating the call method.
   final _self;
 
-  /// The method name.
-  final String _target;
+  /// The method.
+  final _target;
 
-  /// The receiver.
+  /// The receiver. Null if [_self] is not an interceptor.
   final _receiver;
 
+  /// The name of the function. Only used by the mirror system.
+  final String _name;
+
   bool operator==(other) {
     if (identical(this, other)) return true;
     if (other is! BoundClosure) return false;
@@ -1511,17 +1516,30 @@
   }
 
   int get hashCode {
-    return JS('int', '(# + # + #) & 0x3ffffff',
-        _self.hashCode,
-        _target.hashCode,
-        _receiver.hashCode);
+    int receiverHashCode;
+    if (_receiver == null) {
+      // A bound closure on a regular Dart object, just use the
+      // identity hash code.
+      receiverHashCode = Primitives.objectHashCode(_self);
+    } else if (JS('String', 'typeof #', _receiver) != 'object') {
+      // A bound closure on a primitive JavaScript type. We
+      // use the hashCode method we define for those primitive types.
+      receiverHashCode = _receiver.hashCode;
+    } else {
+      // A bound closure on an intercepted native class, just use the
+      // identity hash code.
+      receiverHashCode = Primitives.objectHashCode(_receiver);
+    }
+    return receiverHashCode ^ Primitives.objectHashCode(_target);
   }
 
   static selfOf(BoundClosure closure) => closure._self;
 
-  static String targetOf(BoundClosure closure) => closure._target;
+  static targetOf(BoundClosure closure) => closure._target;
 
-  static revceiverOf(BoundClosure closure) => closure._receiver;
+  static receiverOf(BoundClosure closure) => closure._receiver;
+
+  static nameOf(BoundClosure closure) => closure._name;
 }
 
 bool jsHasOwnProperty(var jsObject, String property) {
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index d16178b..948a0d8 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -279,7 +279,7 @@
     if (mirror is JsMethodMirror) {
       JsMethodMirror method = mirror;
       if (!method.canInvokeReflectively()) {
-        throwInvalidReflectionError(memberName);
+        throwInvalidReflectionError(n(memberName));
       }
     }
     return reflect(mirror._invoke(positionalArguments, namedArguments));
@@ -1063,7 +1063,7 @@
           this, memberName, positionalArguments, namedArguments);
     }
     if (!mirror.canInvokeReflectively()) {
-      throwInvalidReflectionError(memberName);
+      throwInvalidReflectionError(n(memberName));
     }
     return reflect(mirror._invoke(positionalArguments, namedArguments));
   }
@@ -1221,14 +1221,17 @@
       throw new RuntimeError('Cannot find callName on "$reflectee"');
     }
     int parameterCount = int.parse(callName.split(r'$')[1]);
-    bool isStatic = true; // TODO(ahe): Compute isStatic correctly.
     if (reflectee is BoundClosure) {
       var target = BoundClosure.targetOf(reflectee);
       var self = BoundClosure.selfOf(reflectee);
-      cachedFunction = new JsMethodMirror(
-          s(target), JS('', '#[#]', self, target), parameterCount,
-          false, false, isStatic, false, false);
+      var name = mangledNames[BoundClosure.nameOf(reflectee)];
+      if (name == null) {
+        throwInvalidReflectionError(name);
+      }
+      cachedFunction = new JsMethodMirror.fromUnmangledName(
+          name, target, false, false);
     } else {
+      bool isStatic = true; // TODO(ahe): Compute isStatic correctly.
       var jsFunction = JS('', '#[#]', reflectee, callName);
       cachedFunction = new JsMethodMirror(
           s(callName), jsFunction, parameterCount,
diff --git a/sdk/lib/_internal/pub/lib/src/http.dart b/sdk/lib/_internal/pub/lib/src/http.dart
index 9fc338e..f9e63bb 100644
--- a/sdk/lib/_internal/pub/lib/src/http.dart
+++ b/sdk/lib/_internal/pub/lib/src/http.dart
@@ -99,6 +99,8 @@
               '"${request.url.origin}".');
         }
       }
+      print('Error in PubHttpClient.send (issue 12581) error: $error');
+      print('    stacktrace: $stackTrace');
       throw error;
     }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
   }
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index ddeec59..6b6c760 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -5,7 +5,9 @@
 part of dart.async;
 
 /**
- * A [Future] represents a delayed computation. It is used to obtain a not-yet
+ * An object representing a delayed computation.
+ *
+ * A [Future] is used to obtain a not yet
  * available value, or error, sometime in the future.  Receivers of a
  * [Future] can register callbacks that handle the value or error once it is
  * available. For example:
@@ -358,23 +360,33 @@
 }
 
 /**
- * A [Completer] is used to produce [Future]s and to complete those futures
- * with a value or error at a later time.
+ * A way to produce Future objects and to complete them later
+ * with a value or error.
  *
- * A class that wants to return [Future]s can use a [Completer] as follows:
+ * If you already have a Future, you probably don't need a Completer.
+ * Instead, you can usually use [Future.then], which returns a Future:
+ * 
+ *     Future doStuff(){
+ *       return someAsyncOperation().then((result) {
+ *         // Do something.
+ *       });
+ *     }
  *
- *     Class myAsyncOperation {
+ * If you do need to create a Future from scratch—for example,
+ * when you're converting a callback-based API into a Future-based
+ * one—you can use a Completer as follows:
+ *
+ *     Class AsyncOperation {
  *       Completer _completer = new Completer();
  *
- *       Future<T> myOp() {
+ *       Future<T> doOperation() {
  *         _startOperation();
- *         // send future object back to client...
- *         return _completer.future;
+ *         return _completer.future; // Send future object back to client.
  *       }
  *
  *       // Something calls this when the value is ready.
  *       _finishOperation(T result) {
- *         _completer.complete(value);
+ *         _completer.complete(result);
  *       }
  *
  *       // If something goes wrong, call this.
@@ -382,7 +394,6 @@
  *         _completer.completeError(error);
  *       }
  *     }
- *
  */
 abstract class Completer<T> {
 
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index bd1da92..87741a0 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -375,7 +375,7 @@
     try {
       _handleError(error);
     } catch(e, s) {
-      if (identical(e, s)) {
+      if (identical(e, error)) {
         _parentZone.handleUncaughtError(error);
       } else {
         _parentZone.handleUncaughtError(_asyncError(e, s));
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 9ac401b5..4bcf2d3 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -147,7 +147,7 @@
  * for more coverage of classes in this package.
  *
  * The 
- * [Dart Language Specification](https://www.dartlang.org/docs/spec/)
+ * [Dart Language Specification](http://www.dartlang.org/docs/spec/)
  * provides technical details.
  */
 library dart.core;
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index 2ef7f74..9514951 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.dart
@@ -5,7 +5,7 @@
 part of dart.core;
 
 /**
- * Super-type of all function types.
+ * The base class for all function types.
  *
  * A function value, or an instance of a class with a "call" method, is a
  * subtype of a function type, and as such, a subtype of [Function].
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 2b1b70c..a5235bb 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -5,18 +5,15 @@
 part of dart.core;
 
 /**
- * Representation of Dart integers containing integer specific
- * operations and specialization of operations inherited from [num].
+ * An arbitrarily large integer.
  *
- * Integers can be arbitrarily large in Dart.
- *
- * *Note however, that when compiling to JavaScript, integers are
+ * **Note:** When compiling to JavaScript, integers are
  * implemented as JavaScript numbers. When compiling to JavaScript,
  * integers are therefore restricted to 53 significant bits because
  * all JavaScript numbers are double-precision floating point
  * values. The behavior of the operators and methods in the [int]
  * class therefore sometimes differs between the Dart VM and Dart code
- * compiled to JavaScript.*
+ * compiled to JavaScript.
  *
  * It is a compile-time error for a class to attempt to extend or implement int.
  */
diff --git a/sdk/lib/core/iterator.dart b/sdk/lib/core/iterator.dart
index e251df6..ed7aca9 100644
--- a/sdk/lib/core/iterator.dart
+++ b/sdk/lib/core/iterator.dart
@@ -5,24 +5,30 @@
 part of dart.core;
 
 /**
- * The [Iterator] class provides methods to iterate over an object. It
- * is transparently used by the for-in construct to test for the end
- * of the iteration, and to get the elements.
+ * An interface for getting items, one at a time, from an object.
+ *
+ * The for-in construct transparently uses Iterator to test for the end
+ * of the iteration, and to get each item (or _element_).
  *
  * If the object iterated over is changed during the iteration, the
  * behavior is unspecified.
  *
- * The [Iterator] is initially positioned before the first element. Before
+ * The Iterator is initially positioned before the first element. Before
  * accessing the first element the iterator must thus be advanced ([moveNext])
- * to point to the first element. If there is no element left, then [moveNext]
+ * to point to the first element. If no element is left, then [moveNext]
  * returns false.
  *
- * A typical usage of an [Iterator] looks as follows:
+ * A typical usage of an Iterator looks as follows:
  *
  *     var it = obj.iterator;
  *     while (it.moveNext()) {
  *       use(it.current);
  *     }
+ *
+ * **See also:** [Iteration]
+ * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-iteration)
+ * in the [library tour]
+ * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
  */
 abstract class Iterator<E> {
   /**
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index b35a5ad..e5ac21a 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -5,9 +5,9 @@
 part of dart.core;
 
 /**
- * All numbers in dart are instances of [num].
+ * An integer or floating-point number.
  *
- * It is a compile-time error for any type other than the types int and double
+ * It is a compile-time error for any type other than [int] or [double]
  * to attempt to extend or implement num.
  */
 abstract class num implements Comparable<num> {
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 737f916..975a8a7 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -5,7 +5,18 @@
 part of dart.core;
 
 /**
- * Everything in Dart is an [Object].
+ * The base class for all Dart objects.
+ *
+ * Because Object is the root of the Dart class hierarchy,
+ * every other Dart class is a subclass of Object.
+ *
+ * When you define a class, you should override [toString]
+ * to return a string describing an instance of that class.
+ * You might also need to define [hashCode] and [==], as described in the
+ * [Implementing map keys]
+ * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-implementing-map-keys)
+ * section of the [library tour]
+ * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html).
  */
 class Object {
   /**
diff --git a/sdk/lib/core/pattern.dart b/sdk/lib/core/pattern.dart
index d85c8ac..92ac07e 100644
--- a/sdk/lib/core/pattern.dart
+++ b/sdk/lib/core/pattern.dart
@@ -4,6 +4,9 @@
 
 part of dart.core;
 
+/**
+ * An interface for basic searches within strings.
+ */
 abstract class Pattern {
   /**
    * Match this pattern against the string repeatedly.
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index 815c52a..f3b015e 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -5,13 +5,13 @@
 part of dart.core;
 
 /**
- * [Match] contains methods to manipulate a pattern match.
+ * A result from searching within a string.
  *
- * A [Match] or and iterable of [Match] objects are returned from [Pattern]
+ * A Match or an [Iterable] of Match objects is returned from [Pattern]
  * matching methods.
  *
  * The following example finds all matches of a [RegExp] in a [String]
- * and iterates through the returned iterable of [Match] objects.
+ * and iterates through the returned iterable of Match objects.
  *
  *     RegExp exp = new RegExp(r"(\w+)");
  *     String str = "Parse my string";
@@ -28,7 +28,7 @@
  *     string
  *
  * Some patterns, regular expressions in particular, may record subtrings
- * that were part of the matching. These are called "groups" in the `Match`
+ * that were part of the matching. These are called _groups_ in the Match
  * object. Some patterns may never have any groups, and their matches always
  * have zero [groupCount].
  */
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index aaab5ec..bd6aded 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -5,13 +5,13 @@
 part of dart.core;
 
 /**
- * A `Set` is a collection of elements where each element can occur only once.
+ * A collection of objects in which each object can occur only once.
  *
  * That is, for each object of the element type, the object is either considered
- * to be in the set, or it is not in the set.
+ * to be in the set, or to _not_ be in the set. 
  *
  * Set implementations may consider some elements indistinguishable. These
- * objects will be treated as being the same for any operation on the set.
+ * elements are treated as being the same for any operation on the set.
  *
  * The default `Set` implementation, [HashSet], considers objects
  * indistinguishable if they are equal with regard to [Object.operator==].
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index aa00f63..328b995 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -5,7 +5,15 @@
 part of dart.core;
 
 /**
- * A parsed URI, as specified by RFC-3986, http://tools.ietf.org/html/rfc3986.
+ * A parsed URI, such as a URL.
+ *
+ * **See also:**
+ *
+ * * [URIs][uris] in the [library tour][libtour]
+ * * [RFC-3986](http://tools.ietf.org/html/rfc3986)
+ *
+ * [uris]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-uri
+ * [libtour]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
  */
 class Uri {
   final String _host;
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index d5bf1dd..21dbe97 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -102,9 +102,6 @@
 _callPortSync(int id, message) {
   return JS('var', r'ReceivePortSync.dispatchCall(#, #)', id, message);
 }
-
-Future<SendPort> spawnDomFunction(Function f) =>
-  new Future.value(IsolateNatives.spawnDomFunction(f));
 // 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.
@@ -6950,6 +6947,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+@DocsEditable
 /**
  * The base class for all documents.
  *
@@ -8765,6 +8763,7 @@
 
 }
 
+@DocsEditable
 /**
  * An abstract class, which all HTML elements extend.
  */
@@ -24670,6 +24669,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+@DocsEditable
 @DomName('Window')
 class Window extends EventTarget implements WindowBase, WindowTimers, WindowBase64 native "Window,DOMWindow" {
 
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 4682b6c..4a62082 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -7492,6 +7492,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+@DocsEditable
 /**
  * The base class for all documents.
  *
@@ -9345,6 +9346,7 @@
 
 }
 
+@DocsEditable
 /**
  * An abstract class, which all HTML elements extend.
  */
@@ -26677,6 +26679,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+@DocsEditable
 @DomName('Window')
 class Window extends EventTarget implements WindowBase, WindowTimers, WindowBase64 {
 
@@ -34437,25 +34440,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-_makeSendPortFuture(spawnRequest) {
-  final completer = new Completer<SendPort>.sync();
-  final port = new ReceivePort();
-  port.receive((result, _) {
-    completer.complete(result);
-    port.close();
-  });
-  // TODO: SendPort.hashCode is ugly way to access port id.
-  spawnRequest(port.toSendPort().hashCode);
-  return completer.future;
-}
-
-// This API is exploratory.
-Future<SendPort> spawnDomFunction(Function f) =>
-    _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
-
-Future<SendPort> spawnDomUri(String uri) =>
-    _makeSendPortFuture((portId) { _Utils.spawnDomUri(uri, portId); });
-
 // testRunner implementation.
 // FIXME: provide a separate lib for testRunner.
 
@@ -34494,6 +34478,8 @@
     if (invocation.isGetter) {
       return _data[member];
     } else if (invocation.isSetter) {
+      assert(member.endsWith('='));
+      member = member.substring(0, member.length - 1);
       _data[member] = invocation.positionalArguments[0];
     } else {
       return Function.apply(_data[member], invocation.positionalArguments, invocation.namedArguments);
@@ -34573,7 +34559,6 @@
   static window() native "Utils_window";
   static forwardingPrint(String message) native "Utils_forwardingPrint";
   static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
-  static void spawnDomUri(String uri, int replyTo) native "Utils_spawnDomUri";
   static int _getNewIsolateId() native "Utils_getNewIsolateId";
 
   // The following methods were added for debugger integration to make working
@@ -34612,7 +34597,9 @@
    * expression for a closure with a body matching the original expression
    * where locals are passed in as arguments. Returns a list containing the
    * String expression for the closure and the list of arguments that should
-   * be passed to it.
+   * be passed to it. The expression should then be evaluated using
+   * Dart_EvaluateExpr which will generate a closure that should be invoked
+   * with the list of arguments passed to this method.
    *
    * For example:
    * <code>wrapExpressionAsClosure("foo + bar", ["bar", 40, "foo", 2])</code>
@@ -34625,6 +34612,12 @@
     addArg(arg, value) {
       arg = stripMemberName(arg);
       if (args.containsKey(arg)) return;
+      // We ignore arguments with the name 'this' rather than throwing an
+      // exception because Dart_GetLocalVariables includes 'this' and it
+      // is more convenient to filter it out here than from C++ code.
+      // 'this' needs to be handled by calling Dart_EvaluateExpr with
+      // 'this' as the target rather than by passing it as an argument.
+      if (arg == 'this') return;
       if (args.isNotEmpty) {
         sb.write(", ");
       }
@@ -34845,8 +34838,28 @@
   bool get isNotEmpty => Maps.isNotEmpty(this);
 }
 
+// TODO(vsm): Remove DOM isolate code.  This is only used to support
+// printing and timers in background isolates.  Background isolates
+// should just forward to the main DOM isolate instead of requiring a
+// special DOM isolate.
+
+_makeSendPortFuture(spawnRequest) {
+  final completer = new Completer<SendPort>.sync();
+  final port = new ReceivePort();
+  port.receive((result, _) {
+    completer.complete(result);
+    port.close();
+  });
+  // TODO: SendPort.hashCode is ugly way to access port id.
+  spawnRequest(port.toSendPort().hashCode);
+  return completer.future;
+}
+
+Future<SendPort> _spawnDomFunction(Function f) =>
+    _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
+
 final Future<SendPort> __HELPER_ISOLATE_PORT =
-    spawnDomFunction(_helperIsolateMain);
+    _spawnDomFunction(_helperIsolateMain);
 
 // Tricky part.
 // Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 05f50b4..5d60866 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -219,7 +219,7 @@
  * MessageEvents.  Mutating the object to make it more 'Dart-like' would corrupt
  * the value as seen from the JavaScript listeners.
  */
-convertNativeToDart_AcceptStructuredClone(object, {mustCopy = false}) {
+convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) {
 
   // TODO(sra): Replace slots with identity hash table that works on non-dart
   // objects.
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 3cbf4d5..9c9eb23 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -5,7 +5,7 @@
 part of dart.io;
 
 /**
- * [Directory] objects are used for working with directories.
+ * A reference to a directory (or _folder_) on the file system.
  */
 abstract class Directory implements FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 4f9d3f5..ae08c22 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -20,7 +20,7 @@
 const APPEND = FileMode.APPEND;
 
 /**
- * [File] objects are references to files.
+ * A reference to a file on the file system.
  *
  * If [path] is a symbolic link, rather than a file, then
  * the methods of [File] operate on the ultimate target of the
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 83cd223..474aa51 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -22,7 +22,8 @@
    * On the Windows platform, this will only work with directories, and the
    * target directory must exist. The link will be created as a Junction.
    * Only absolute links will be created, and relative paths to the target
-   * will be converted to absolute paths.
+   * will be converted to absolute paths by joining them with the path of the
+   * directory the link is contained in.
    *
    * On other platforms, the posix symlink() call is used to make a symbolic
    * link containing the string [target].  If [target] is a relative path,
@@ -170,24 +171,17 @@
 
   // Put target into the form "\??\C:\my\target\dir".
   String _makeWindowsLinkTarget(String target) {
-    if (target.startsWith('\\??\\')) {
-      return target;
-    }
-    if (!(target.length > 3 && target[1] == ':' && target[2] == '\\')) {
-      try {
-        target = new File(target).fullPathSync();
-      } on FileException catch (e) {
-        throw new LinkException('Could not locate target', target, e.osError);
-      }
-    }
-    if (target.length > 3 && target[1] == ':' && target[2] == '\\') {
-      target = '\\??\\$target';
+    Uri base = new Uri.file('${Directory.current.path}\\');
+    Uri link = new Uri.file(path);
+    Uri destination = new Uri.file(target);
+    String result = base.resolveUri(link).resolveUri(destination).toFilePath();
+    if (result.length > 3 && result[1] == ':' && result[2] == '\\') {
+      return '\\??\\$result';
     } else {
       throw new LinkException(
-          'Target $target of Link.create on Windows cannot be converted' +
+          'Target $result of Link.create on Windows cannot be converted' +
           ' to start with a drive letter.  Unexpected error.');
     }
-    return target;
   }
 
   void updateSync(String target) {
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index be4a8ff..25bce63 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -5,8 +5,10 @@
 part of dart.math;
 
 /**
- * A random number generator. The default implementation supplies a stream of
- * pseudo-random bits which is not suitable for cryptographic purposes.
+ * A generator of random bool, int, or double values.
+ *
+ * The default implementation supplies a stream of
+ * pseudo-random bits that are not suitable for cryptographic purposes.
  */
 abstract class Random {
   /**
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 2cdbc44..5ded114 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -102,6 +102,9 @@
 LibTest/core/String/concat_A02_t01: Fail  # co19 issue 561
 LibTest/core/String/hashCode_A01_t01: Fail  # co19 issue 561
 
+[ $compiler == dart2dart || $compiler == dart2js ]
+Language/14_Libraries_and_Scripts/1_Imports_A03_t49: Fail # co19 Issue 590
+
 ### CHECKED MODE FAILURES ###
 
 [ ($runtime == vm || $compiler == dart2js) && $checked]
@@ -121,4 +124,3 @@
 LibTest/core/TypeError/srcType_A01_t01: FAIL, OK # co19 issue 510
 LibTest/core/TypeError/url_A01_t01: FAIL, OK # co19 issue 510
 LibTest/core/Uri/encodeFull_A01_t02: fail # co19 Issue 589
-
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 91b835e..369134f 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -36,8 +36,6 @@
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t14: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t15: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t01: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t02: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # inherited from VM
@@ -256,14 +254,7 @@
 Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t47: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t48: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t49: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t50: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t67: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t68: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t69: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t70: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A04_t03: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index e794031..8f61e3a 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -178,8 +178,6 @@
 Language/03_Overview/1_Scoping_A01_t41: Fail, OK # co19 issue 188
 Language/03_Overview/2_Privacy_A01_t09: Fail, OK # co19 issue 198
 Language/03_Overview/2_Privacy_A01_t11: Pass, OK # co19 issue 316
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t14: Fail, OK # co19 issue 210
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t15: Fail, OK # co19 issue 210
 Language/06_Functions/4_External_Functions_A01_t01: Fail, OK # http://dartbug.com/5021
 LibTest/core/int/hashCode_A01_t01: Fail, OK # co19 issue 308
 LibTest/typed_data/Int64List/*: Fail # co19-roll r559: Please triage this failure
@@ -484,14 +482,6 @@
 Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t47: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t48: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t49: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t50: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t67: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t68: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t69: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t70: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A04_t03: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 972dd6a..f160171 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -180,9 +180,11 @@
 LibTest/typed_data/Float32x4List/take_A01_t01: Fail # Dart issue 12861
 LibTest/typed_data/Float32x4List/take_A02_t01: Fail # Dart issue 12861
 
+[ $compiler == none && $runtime == vm && $system == windows && $mode == debug ]
+Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # Issue 13349
+Language/15_Types/4_Interface_Types_A11_t02: pass, timeout # Issue 13349
+
 [ $compiler == none && $runtime == vm && $system == windows ]
-Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # co19-roll r576: Please triage this failure
-Language/15_Types/4_Interface_Types_A11_t02: pass, timeout # co19-roll r576: Please triage this failure
-LibTest/core/Uri/toFilePath_A02_t01: fail # co19-roll r576: Please triage this failure
-LibTest/core/Uri/Uri.file_A01_t01: fail # co19-roll r576: Please triage this failure
+LibTest/core/Uri/toFilePath_A02_t01: fail # co19 Issue 594
+LibTest/core/Uri/Uri.file_A01_t01: fail # co19 Issue 594
 
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index e026f90..cc7d02c 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -9,8 +9,6 @@
 import '../../../sdk/lib/_internal/compiler/compiler.dart'
        show Diagnostic;
 
-import 'dart:json';
-
 main() {
   Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
@@ -37,20 +35,10 @@
     var expected = [
         'memory:exporter.dart:43:47:Info: "function(hest)" is defined here.'
         ':info',
-        'memory:library.dart:14:19:Info: "class(Fisk)" is (re)exported by '
-        'multiple libraries.:info',
-        'memory:library.dart:30:34:Info: "function(fisk)" is (re)exported by '
-        'multiple libraries.:info',
         'memory:library.dart:41:45:Info: "function(hest)" is defined here.'
         ':info',
-        'memory:main.dart:0:22:Info: "class(Fisk)" is imported here.:info',
-        'memory:main.dart:0:22:Info: "function(fisk)" is imported here.:info',
         'memory:main.dart:0:22:Info: "function(hest)" is imported here.:info',
-        'memory:main.dart:23:46:Info: "class(Fisk)" is imported here.:info',
-        'memory:main.dart:23:46:Info: "function(fisk)" is imported here.:info',
         'memory:main.dart:23:46:Info: "function(hest)" is imported here.:info',
-        'memory:main.dart:59:63:Warning: Duplicate import of "Fisk".:warning',
-        'memory:main.dart:76:80:Error: Duplicate import of "fisk".:error',
         'memory:main.dart:86:90:Error: Duplicate import of "hest".:error'
     ];
     Expect.listEquals(expected, diagnostics);
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
new file mode 100644
index 0000000..8ca8614
--- /dev/null
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -0,0 +1,56 @@
+// 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 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+const String TEST = """
+bar() => 42;
+baz() => bar;
+
+class A {
+  foo() => 42;
+}
+
+class B extends A {
+  foo() => super.foo;
+}
+
+main() {
+  baz();
+  new B().foo();
+}
+""";
+
+void main() {
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(TEST, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    var typesTask = compiler.typesTask;
+    var typesInferrer = typesTask.typesInferrer;
+
+    checkReturn(String name, type) {
+      var element = findElement(compiler, name);
+      Expect.equals(
+          type,
+          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          name);
+    }
+
+    checkReturnInClass(String className, String methodName, type) {
+      var cls = findElement(compiler, className);
+      var element = cls.lookupLocalMember(buildSourceString(methodName));
+      Expect.equals(type,
+          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+    }
+
+    checkReturn('bar', typesTask.intType);
+    checkReturn('baz', typesTask.functionType);
+
+    checkReturnInClass('A', 'foo', typesTask.intType);
+    checkReturnInClass('B', 'foo', typesTask.functionType);
+  }));
+}
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index b702d02..4c513ea 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -19,7 +19,15 @@
   Expect.isNotNull(kind.howToFix);
   Expect.isFalse(kind.examples.isEmpty);
 
-  for (String example in kind.examples) {
+  return Future.forEach(kind.examples, (example) {
+    if (example is String) {
+      example = {'main.dart': example};
+    } else {
+      Expect.isTrue(example is Map,
+                    "Example must be either a String or a Map.");
+      Expect.isTrue(example.containsKey('main.dart'),
+                    "Example map must contain a 'main.dart' entry.");
+    }
     List<String> messages = <String>[];
     void collect(Uri uri, int begin, int end, String message, kind) {
       if (kind.name == 'verbose info') {
@@ -29,7 +37,7 @@
     }
 
     Compiler compiler = compilerFor(
-        {'main.dart': example},
+        example,
         diagnosticHandler: collect,
         options: ['--analyze-only'],
         cachedCompiler: cachedCompiler);
@@ -53,9 +61,7 @@
         }
       }
       Expect.isTrue(messageFound, '"$pattern" does not match any in $messages');
-      return compiler;
+      cachedCompiler = compiler;
     });
-  }
-
-  return new Future<Compiler>.sync(cachedCompiler);
+  }).then((_) => cachedCompiler);
 }
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
new file mode 100644
index 0000000..fcedf81
--- /dev/null
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that final fields in @MirrorsUsed are still inferred.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_compiler.dart' show compilerFor;
+import 'compiler_helper.dart' show findElement;
+
+const MEMORY_SOURCE_FILES = const <String, String> {
+  'main.dart': """
+import 'dart:mirrors';
+
+const field = 42;
+
+main() {
+  var mirror = reflect(field);
+  mirror.invoke(null, null);
+}
+"""
+};
+
+void main() {
+  var compiler = compilerFor(MEMORY_SOURCE_FILES);
+  asyncTest(() => compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
+    var element = findElement(compiler, 'field');
+    var typesTask = compiler.typesTask;
+    var typesInferrer = typesTask.typesInferrer;        
+    Expect.equals(typesTask.intType,
+                  typesInferrer.getTypeOfElement(element).simplify(compiler),
+                  'field');
+  }));
+}
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
new file mode 100644
index 0000000..fb0c0a1
--- /dev/null
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that final fields in @MirrorsUsed are still inferred.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_compiler.dart' show compilerFor;
+import 'compiler_helper.dart' show findElement;
+
+const MEMORY_SOURCE_FILES = const <String, String> {
+  'main.dart': """
+@MirrorsUsed(targets: 'field')
+import 'dart:mirrors';
+
+const field = 42;
+
+main() {
+  return field;
+}
+"""
+};
+
+void main() {
+  var compiler = compilerFor(MEMORY_SOURCE_FILES);
+  asyncTest(() => compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
+    var element = findElement(compiler, 'field');
+    var typesTask = compiler.typesTask;
+    var typesInferrer = typesTask.typesInferrer;        
+    Expect.equals(typesTask.intType,
+                  typesInferrer.getTypeOfElement(element).simplify(compiler),
+                  'field');
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 4c0a807..065da51 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -30,6 +30,11 @@
     print(message);
     return;
   }
+  if (message.contains('methods retained for use by dart:mirrors out of')) {
+    print(message);
+    return;
+  }
+  if (kind.name == 'info') return;
   throw '$uri:$begin:$end: $kind: $message';
 }
 
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index b4494bc..0a6bfc2 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -52,12 +52,12 @@
   boolConversionCheck(x) {}
   abstract class JavaScriptIndexingBehavior {}
   class JSInvocationMirror {}
-  class BoundClosure {
+  class BoundClosure extends Closure {
     var self;
     var target;
     var receiver;
   }
-  class Closure {}
+  class Closure implements Function {}
   class Null {}
   class Dynamic_ {}
   class LinkedHashMap {}
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 4b4c762..3d8a353 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -32,6 +32,32 @@
   void log(message) {
     print(message);
   }
+
+  void internalErrorOnElement(element, String message) {
+    log(message);
+  }
+
+  void internalError(String message, {node, token, instruction, element}) {
+    log(message);
+  }
+
+  SourceSpan spanFromSpannable(node, [uri]) {
+    throw 'unsupported operation';
+  }
+
+  void reportMessage(SourceSpan span, Diagnostic message, kind) {
+    log(message);
+  }
+
+  void reportError(Spannable node, MessageKind errorCode, [Map arguments]) {
+    log(new Message(errorCode, arguments, false));
+  }
+
+  void reportInfo(Spannable node, MessageKind errorCode, [Map arguments]) {
+    log(new Message(errorCode, arguments, false));
+  }
+
+  withCurrentElement(Element element, f()) => f();
 }
 
 Token scan(String text) => new StringScanner(text).tokenize();
diff --git a/tests/corelib/string_operations_with_null_test.dart b/tests/corelib/string_operations_with_null_test.dart
new file mode 100644
index 0000000..7288001
--- /dev/null
+++ b/tests/corelib/string_operations_with_null_test.dart
@@ -0,0 +1,19 @@
+// 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 "package:expect/expect.dart";
+import "../language/compiler_annotations.dart";
+
+@DontInline()
+returnStringOrNull() {
+  () => 42;
+  return new DateTime.now().millisecondsSinceEpoch == 0 ? 'foo' : null;
+}
+
+main() {
+  Expect.throws(() => 'foo' + returnStringOrNull(),
+                (e) => e is ArgumentError);
+  Expect.throws(() => 'foo'.split(returnStringOrNull()),
+                (e) => e is ArgumentError || e is NoSuchMethodError);
+}
diff --git a/tests/corelib/uri_http_test.dart b/tests/corelib/uri_http_test.dart
index 95614f7..283d995 100644
--- a/tests/corelib/uri_http_test.dart
+++ b/tests/corelib/uri_http_test.dart
@@ -66,7 +66,17 @@
   check(new Uri.https("[::127.0.0.1]", "a"), "https://[::127.0.0.1]/a");
 }
 
+testResolveHttpScheme() {
+  String s = "//myserver:1234/path/some/thing";
+  Uri uri = Uri.parse(s);
+  Uri http = new Uri(scheme: "http");
+  Uri https = new Uri(scheme: "https");
+  Expect.equals("http:$s", http.resolveUri(uri).toString());
+  Expect.equals("https:$s", https.resolveUri(uri).toString());
+}
+
 main() {
   testHttpUri();
   testHttpsUri();
+  testResolveHttpScheme();
 }
diff --git a/tests/html/dom_isolates_test.dart b/tests/html/dom_isolates_test.dart
deleted file mode 100644
index 39092bc..0000000
--- a/tests/html/dom_isolates_test.dart
+++ /dev/null
@@ -1,81 +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 DOMIsolatesTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-import 'dart:isolate';
-
-childDomIsolate() {
-  port.receive((msg, replyTo) {
-    if (msg != 'check') {
-      replyTo.send('wrong msg: $msg');
-    }
-    replyTo.send('${window.location}');
-    port.close();
-  });
-}
-
-trampolineIsolate() {
-  final future = spawnDomFunction(childDomIsolate);
-  port.receive((msg, parentPort) {
-    future.then((childPort) {
-      childPort.call(msg).then((response) {
-        parentPort.send(response);
-        port.close();
-      });
-    });
-  });
-}
-
-dummy() => print('Bad invocation of top-level function');
-
-main() {
-  useHtmlConfiguration();
-
-  test('Simple DOM isolate test', () {
-    spawnDomFunction(childDomIsolate).then(expectAsync1(
-        (sendPort) {
-            expect(sendPort.call('check'), completion('${window.location}'));
-        }
-    ));
-  });
-
-  test('Nested DOM isolates test', () {
-    spawnDomFunction(trampolineIsolate).then(expectAsync1(
-        (sendPort) {
-            expect(sendPort.call('check'), completion('${window.location}'));
-        }
-    ));
-  });
-
-  test('Spawn DOM isolate from pure', () {
-    expect(spawnFunction(trampolineIsolate).call('check'),
-           completion('${window.location}'));
-  });
-
-  test('Spawn DOM by uri', () {
-    spawnDomUri('dom_isolates_test.dart.child_isolate.dart').then(expectAsync1(
-        (sendPort) {
-            expect(sendPort.call('check'), completion('${window.location}'));
-        }
-    ));
-  });
-
-  test('Not function', () {
-      expect(() => spawnDomFunction(42), throws);
-  });
-
-  test('Not topLevelFunction', () {
-    var closure = guardAsync(() {});
-    expect(() => spawnDomFunction(closure), throws);
-  });
-
-  test('Masked local function', () {
-    var local = 42;
-    dummy() => print('Bad invocation of local function: $local');
-    expect(() => spawnDomFunction(dummy), throws);
-  });
-}
diff --git a/tests/html/html.status b/tests/html/html.status
index 812076a..ac55ad5 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -6,6 +6,9 @@
 event_test: Skip  # Issue 1996
 interactive_test: Skip # Must be run manually.
 
+[ $compiler == dart2js && $browser ]
+element_offset_test/offset: Pass, Fail # Issue 13296
+
 [ $compiler == dart2js && $runtime != drt && $browser ]
 custom/document_register_type_extensions_test/namespaces: Fail # Polyfill does not support createElementNS
 custom/document_register_basic_test: Fail # Polyfill is not case-sensitive
@@ -30,9 +33,6 @@
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
 
-[ $compiler == dart2js && ($runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == opera || $runtime == drt || $runtime == dartium)]
-dom_isolates_test: Skip # Need to migrate to new spawnDomFunction.
-
 [ $compiler == dart2js && $runtime == ie10 ]
 async_test: Pass, Fail # timers test fails on ie10.
 indexeddb_5_test: Fail # Issue 12893
diff --git a/tests/html/js_interop_4_test.dart b/tests/html/js_interop_4_test.dart
index 944506b..3aee526 100644
--- a/tests/html/js_interop_4_test.dart
+++ b/tests/html/js_interop_4_test.dart
@@ -11,14 +11,6 @@
 
 const testData = const [1, '2', 'true'];
 
-void testIsolateEntry() {
-  var fun1 = window.lookupPort('fun1');
-  var result = fun1.callSync(testData);
-
-  var fun2 = window.lookupPort('fun2');
-  fun2.callSync(result);
-}
-
 main() {
   useHtmlConfiguration();
 
@@ -37,29 +29,4 @@
     var result = port2.callSync(testData);
     expect(result, 3);
   });
-
-  // Test across isolate boundary.
-  test('dart-to-dart-cross-isolate', () {
-    var fun1 = (message) {
-      expect(message, orderedEquals(testData));
-      return message.length;
-    };
-
-    var port1 = new ReceivePortSync();
-    port1.receive(fun1);
-    window.registerPort('fun1', port1.toSendPort());
-
-    // TODO(vsm): Investigate why this needs to be called asynchronously.
-    var done = expectAsync0(() {});
-    var fun2 = (message) {
-      expect(message, 3);
-      Timer.run(done);
-    };
-
-    var port2 = new ReceivePortSync();
-    port2.receive(fun2);
-    window.registerPort('fun2', port2.toSendPort());
-
-    spawnDomFunction(testIsolateEntry);
-  });
 }
diff --git a/tests/language/cascade2_test.dart b/tests/language/cascade2_test.dart
new file mode 100644
index 0000000..3f6277e
--- /dev/null
+++ b/tests/language/cascade2_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Regression test for dart2js that used to hit an assertion in the
+// container tracer visitor in the presence of cascaded calls.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo;
+
+  add(list) {
+    foo = list;
+    list.add(2.5);
+    return this;
+  }
+
+  call(arg) => arg;
+}
+
+main() {
+  var foo = [42, 0];
+  var a = new A();
+  var bar = a..add(foo)('WHAT');
+  a..foo[0] = new Object();
+  Expect.throws(() => foo[0] + 2, (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/evaluation_redirecting_constructor_test.dart b/tests/language/evaluation_redirecting_constructor_test.dart
new file mode 100644
index 0000000..0fd04f6
--- /dev/null
+++ b/tests/language/evaluation_redirecting_constructor_test.dart
@@ -0,0 +1,24 @@
+// 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 "package:expect/expect.dart";
+
+int counter = 0;
+
+class Bar {
+  Bar() {
+    counter++;
+  }
+}
+
+class A {
+  var _bar = new Bar();
+  A() : this._();
+  A._() {() => 42;}
+}
+
+main() {
+  new A();
+  Expect.equals(1, counter);
+}
diff --git a/tests/language/inference_list_or_null_test.dart b/tests/language/inference_list_or_null_test.dart
new file mode 100644
index 0000000..ae0dfb5
--- /dev/null
+++ b/tests/language/inference_list_or_null_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// Regression test for dart2js that used to statically inline the length of an
+// array held in a variable when it could, even if that variable could
+// be null.
+
+import "package:expect/expect.dart";
+
+var list;
+
+main() {
+  if (new DateTime.now().millisecondsSinceEpoch == 0) list = new List(4);
+  Expect.throws(() => print(list[5]), (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/inlined_conditional_test.dart b/tests/language/inlined_conditional_test.dart
new file mode 100644
index 0000000..f6a22a1
--- /dev/null
+++ b/tests/language/inlined_conditional_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+// Regression test for dart2js. There was a bug in the variable
+// allocator when a pure (side-effect free) instruction stand
+// in-between an inlined `if` and its inlined expression.
+
+import "package:expect/expect.dart";
+
+var topLevel;
+
+// Make [foo] an inlineable expression with a return type check.
+Function foo(c) {
+  // Use [c] twice to make sure it is stored in a local.
+  return (c is Function ? null : c);
+}
+
+bar() {
+  var b = new Object();
+  f() {
+    // Inside a closure, locals that escape are stored in a closure
+    // class. By using [b] in both branches, the optimizers will move
+    // the fetching of [b] before the `if`. This puts the fetching
+    // instruction in between the `if` and the expression of the `if`.
+    // This instruction being pure, the variable allocator was dealing
+    // with it in a special way.
+    //
+    // Because the expression in the `if` is being recognized by the
+    // optimizers as being also a JavaScript expression, we do not
+    // allocate a name for it. But some expressions that it uses still
+    // can have a name, and our variable allocator did not handle live
+    // variables due to the inlining of the ternary expression in [foo].
+    if (foo(topLevel) == null) {
+      return b.toString();
+    } else {
+      return b.hashCode;
+    }
+  }
+  return f();
+}
+
+main() {
+  // Make sure the inferrer does not get an exact type for [topLevel].
+  topLevel = new Object();
+  topLevel = main;
+  var res = bar();
+  Expect.isTrue(res is String);
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 7cd6bc0..60a165a 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -13,6 +13,7 @@
 switch_int_double_test/01: Fail # Issue 7307
 switch_int_double_test/02: Fail # Issue 7307
 symbol_literal_test: Fail # Issue 12171
+evaluation_redirecting_constructor_test: Fail # Issue 13347
 
 # These bugs refer currently ongoing language discussions.
 constructor_initializer_test/none: Fail # Issue 12633
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 6b182de..87285e6 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -120,12 +120,9 @@
 function_type_alias5_test/00: Fail # Issue 12754
 function_type_alias5_test/01: Fail # Issue 12754
 function_type_alias5_test/02: Fail # Issue 12754
-method_binding_test: Fail # Issue 12807
-method_override_test: Fail # Issue 12808
 method_override5_test: Fail # Issue 12809
 parameter_initializer6_negative_test: Fail # Issue 3502
 named_parameters_aggregated_test/03: Fail # Issue 12812
-super_implicit_closure_test: Fail # Issue 12884
 external_test/11: Fail # Issue 12887
 external_test/12: Fail # Issue 12887
 external_test/13: Fail # Issue 12887
@@ -309,6 +306,7 @@
 constructor6_test: Fail
 closure_in_initializer_test: Fail
 super_first_constructor_test: Fail
+evaluation_redirecting_constructor_test: Fail # Issue 13347
 # Minified mode failures.
 
 new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
diff --git a/tests/language/parameter_default_test.dart b/tests/language/parameter_default_test.dart
new file mode 100644
index 0000000..88d4d3d
--- /dev/null
+++ b/tests/language/parameter_default_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+class C {
+  foo(a
+      : 1  /// 01: compile-time error
+      = 1  /// 02: compile-time error
+  ) { print(a); }
+
+  static bar(a
+      : 1  /// 03: compile-time error
+      = 1  /// 04: compile-time error
+  ) { print(a); }
+}
+
+baz(a
+    : 1  /// 05: compile-time error
+    = 1  /// 06: compile-time error
+) { print(a); }
+
+main() {
+  foo(a
+      : 1  /// 07: compile-time error
+      = 1  /// 08: compile-time error
+  ) { print(a); }
+
+  foo(1);
+
+  new C().foo(2);
+
+  C.bar(3);
+
+  baz(4);
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index bc28219..d0b9b70 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -33,6 +33,7 @@
 mirrors/parameter_metadata_test: Fail # Issue 10905
 mirrors/reflected_type_test: Fail # Issue 12607
 mirrors/typedef_metadata_test: Fail # Issue 12785
+mirrors/typevariable_mirror_metadata_test: Fail # Issue 10905
 mirrors/unnamed_library_test: Fail # Issue 10580
 async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9002
 async/run_async4_test: Pass, Fail # no global exception handler in isolates. http://dartbug.com/9012
@@ -40,6 +41,9 @@
 async/stream_controller_async_test: Fail, Pass # http://dartbug.com/11953
 mirrors/typedef_test/none: Fail # http://dartbug.com/6490
 mirrors/typedef_test/02: Fail, OK # Incorrect VM behavior.
+mirrors/redirecting_factory_test/none: Fail # Issue 6490
+mirrors/redirecting_factory_test/02: Fail # Issue 6490
+mirrors/closures_test/none: Fail # Issue 6490
 
 [ $runtime == safari ]
 mirrors/return_type_test: Pass, Timeout # Issue 12858
@@ -129,6 +133,10 @@
 mirrors/hierarchy_test: Fail # TODO(ahe): This test is slightly broken. http://dartbug.com/12464
 mirrors/mixin_test/01: Fail, OK # TODO(ahe): Slight broken test to ensure test coverage on dart2js.
 mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
+mirrors/redirecting_factory_test/none: Fail # Issue 13365
+mirrors/redirecting_factory_test/01: Fail # Issue 13365
+mirrors/redirecting_factory_test/02: Fail # Issue 13365
+mirrors/closures_test/01: Fail, OK # Incorrect dart2js behavior.
 
 [ $compiler == none && $runtime == drt ]
 async/timer_isolate_test: Skip # See Issue 4997
diff --git a/tests/lib/mirrors/closures_test.dart b/tests/lib/mirrors/closures_test.dart
new file mode 100644
index 0000000..5f861c6
--- /dev/null
+++ b/tests/lib/mirrors/closures_test.dart
@@ -0,0 +1,30 @@
+// 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:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+testIntercepted() {
+  var instance = [];
+  var methodMirror = reflect(instance.toString);
+  String rest = ' in s(List)';
+  rest = ''; /// 01: ok
+  expect('Method(s(toString)$rest)', methodMirror.function);
+  Expect.equals('[]', methodMirror.apply([]).reflectee);
+}
+
+testNonIntercepted() {
+  var closure = new Map().containsKey;
+  var mirror = reflect(closure);
+  String rest = ' in s(_HashMap)'; // Might become Map instead.
+  rest = ''; /// 01: ok
+  expect('Method(s(containsKey)$rest)', mirror.function);
+  Expect.isFalse(mirror.apply([7]).reflectee);
+}
+
+main() {
+  testIntercepted();
+  testNonIntercepted();
+}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 3beaf40..df1f9b0 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -196,10 +196,8 @@
 
   instanceMirror = classMirror.newInstance(const Symbol('redirectingFactory'),
                                            [10]);
-  if (!isDart2js) {
-    expect(instanceMirror.reflectee is Class, equals(true));
-    expect(instanceMirror.reflectee.field, equals(30));
-  }
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals(30));
 
 
   var future = classMirror.newInstanceAsync(const Symbol(''), []);
@@ -223,7 +221,6 @@
   var symbolClassMirror = reflectClass(Symbol);
   var symbolMirror = symbolClassMirror.newInstance(const Symbol(''),
                                                    ['withInitialValue']);
-  if (isDart2js) return;
   var objectMirror = classMirror.newInstance(symbolMirror.reflectee,[1234]);
   expect(objectMirror.reflectee is Class, equals(true));
   expect(objectMirror.reflectee.field, equals(1234));
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
new file mode 100644
index 0000000..7da01a2
--- /dev/null
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -0,0 +1,124 @@
+// 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:mirrors";
+import "package:expect/expect.dart";
+import "stringify.dart";
+
+class Class<T1, T2> {
+  final field;
+  Class(this.field);
+
+  factory Class.factoryNoOptional(a, b) => new Class<T1, T2>(a - b);
+  factory Class.redirectingFactoryNoOptional(a, b) = Class.factoryNoOptional;
+
+  factory Class.factoryUnnamedOptional(a, [b = 42]) => new Class<T1, T2>(a - b);
+  factory Class.redirectingFactoryUnnamedOptional(a, [b]) =
+      Class.factoryUnnamedOptional;
+
+  factory Class.factoryNamedOptional(a, {b: 0}) {
+    return new Class<T1, T2>(a - b);
+  }
+
+  factory Class.redirectingFactoryNamedOptional(a, {b: 42}) =
+      Class.factoryNamedOptional;
+
+  factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) {
+    return new Class<T1, T2>(a - b - c);
+  }
+
+  factory Class.redirectingFactoryMoreNamedOptional(a, {b: 42}) =
+      Class.factoryMoreNamedOptional;
+
+  factory Class.factoryMoreUnnamedOptional(a, [b = 0, c = 2]) {
+    return new Class<T1, T2>(a - b - c);
+  }
+
+  factory Class.redirectingFactoryMoreUnnamedOptional(a, [b = 42]) =
+      Class.factoryMoreUnnamedOptional;
+
+  factory Class.redirectingFactoryStringIntTypeParameters(a, b) =
+      Class<String, int>.factoryNoOptional;
+
+  factory Class.redirectingFactoryStringTypeParameters(a, b) =
+      Class
+        <String>  /// 02: static type warning
+      .factoryNoOptional;
+
+  factory Class.redirectingFactoryTypeParameters(a, b) =
+      Class<T1, T2>.factoryNoOptional;
+
+  factory Class.redirectingFactoryReversedTypeParameters(a, b) =
+      Class<T2, T1>.factoryNoOptional;
+}
+
+main() {
+  var classMirror = reflectClass(Class);
+
+  var instanceMirror = classMirror.newInstance(const Symbol(''), [2]);
+  Expect.equals(2, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryNoOptional'), [8, 6]);
+  Expect.equals(2, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryUnnamedOptional'), [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryMoreUnnamedOptional'), [43, 1]);
+  Expect.equals(40, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryStringIntTypeParameters'), [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
+  Expect.isFalse(instanceMirror.reflectee is Class<int, String>);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryStringTypeParameters'), [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, String>);
+  Expect.isTrue(instanceMirror.reflectee is Class<int, String>);
+
+  bool isDart2js = false;
+  isDart2js = true; /// 01: ok
+  if (isDart2js) return;
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryUnnamedOptional'), [43]);
+  Expect.equals(1, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryNamedOptional'), [43]);
+  Expect.equals(1, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryNamedOptional'),
+      [43],
+      new Map()..[const Symbol('b')] = 1);
+  Expect.equals(42, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryMoreNamedOptional'),
+      [43],
+      new Map()..[const Symbol('b')] = 1);
+  Expect.equals(40, instanceMirror.reflectee.field);
+
+  classMirror = reflect(new Class<String, int>(42)).type;
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryTypeParameters'), [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
+  Expect.isFalse(instanceMirror.reflectee is Class<int, String>);
+
+  instanceMirror = classMirror.newInstance(
+      const Symbol('redirectingFactoryReversedTypeParameters'), [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<int, String>);
+  Expect.isFalse(instanceMirror.reflectee is Class<String, int>);
+}
+
diff --git a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
new file mode 100644
index 0000000..77f226b
--- /dev/null
+++ b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
@@ -0,0 +1,48 @@
+// 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 test.typevariable_metadata_test;
+
+import "dart:mirrors";
+
+import "metadata_test.dart";
+
+const m1 = 'm1';
+const m2 = const Symbol('m2');
+const m3 = 3;
+
+class A <S, @m1 @m2 T> {
+  // TODO(13327): Remove this once the name collision is prohibited by the
+  // compiler/runtime.
+  @m3
+  T() => null;
+}
+
+class B <@m3 T> {
+  // TODO(13327): Remove this once the name collision is prohibited by the
+  // compiler/runtime.
+  @m1
+  @m2
+  var T;
+}
+
+typedef bool Predicate<@m1 @m2 G>(G a);
+
+main() {
+  ClassMirror cm;
+  cm = reflectClass(A);
+  checkMetadata(cm.typeVariables[const Symbol('S')], []);
+  checkMetadata(cm.typeVariables[const Symbol('T')], [m1, m2]);
+  // Check for conflicts.
+  checkMetadata(cm.methods[const Symbol('T')], [m3]);
+
+  cm = reflectClass(B);
+  checkMetadata(cm.typeVariables[const Symbol('T')], [m3]);
+  // Check for conflicts.
+  checkMetadata(cm.members[const Symbol('T')], [m1, m2]);
+
+  TypedefMirror tm = reflectClass(Predicate);
+  FunctionTypeMirror ftm = tm.referent;
+  checkMetadata(ftm.typeVariables[const Symbol('G')], [m1, m2]);
+}
diff --git a/tests/lib/typed_data/typed_data_sublist_type_test.dart b/tests/lib/typed_data/typed_data_sublist_type_test.dart
new file mode 100644
index 0000000..e039508
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_sublist_type_test.dart
@@ -0,0 +1,93 @@
+// 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 'package:expect/expect.dart';
+import 'dart:typed_data';
+
+// Test that the sublist of a typed_data list is of the same type.
+
+var inscrutable;
+
+class Is<T> {
+  final name;
+  Is(this.name);
+  check(x) => x is T;
+  expect(x, part) {
+    Expect.isTrue(check(x), '($part: ${x.runtimeType}) is $name');
+  }
+  expectNot(x, part) {
+    Expect.isFalse(check(x), '($part: ${x.runtimeType}) is! $name');
+  }
+}
+
+void testSublistType(input, positive, all) {
+  var negative = all.where((check) => !positive.contains(check));
+
+  input = inscrutable(input);
+
+  for (var check in positive) check.expect(input, 'input');
+  for (var check in negative) check.expectNot(input, 'input');
+
+  var sub = inscrutable(input.sublist(1));
+
+  for (var check in positive) check.expect(sub, 'sublist');
+  for (var check in negative) check.expectNot(sub, 'sublist');
+
+  var sub2 = inscrutable(input.sublist(10));
+
+  Expect.equals(0, sub2.length);
+  for (var check in positive) check.expect(sub2, 'empty sublist');
+  for (var check in negative) check.expectNot(sub2, 'empty sublist');
+}
+
+
+void testTypes() {
+  var isFloat32list = new Is<Float32List>('Float32List');
+  var isFloat64list = new Is<Float64List>('Float64List');
+
+  var isInt8List = new Is<Int8List>('Int8List');
+  var isInt16List = new Is<Int16List>('Int16List');
+  var isInt32List = new Is<Int32List>('Int32List');
+
+  var isUint8List = new Is<Uint8List>('Uint8List');
+  var isUint16List = new Is<Uint16List>('Uint16List');
+  var isUint32List = new Is<Uint32List>('Uint32List');
+
+  var isUint8ClampedList = new Is<Uint8ClampedList>('Uint8ClampedList');
+
+  var isIntList = new Is<List<int>>('List<int>');
+  var isDoubleList = new Is<List<double>>('List<double>');
+  var isNumList = new Is<List<num>>('List<num>');
+
+  var allChecks = [isFloat32list, isFloat64list,
+      isInt8List, isInt16List, isInt32List,
+      isUint8List, isUint16List, isUint32List,
+      isUint8ClampedList];
+
+  testInt(list, check) {
+    testSublistType(list, [check, isIntList, isNumList], allChecks);
+  }
+
+  testDouble(list, check) {
+    testSublistType(list, [check, isDoubleList, isNumList], allChecks);
+  }
+
+  testDouble(new Float32List(10), isFloat32list);
+  testDouble(new Float64List(10), isFloat64list);
+
+  testInt(new Int8List(10), isInt8List);
+  testInt(new Int16List(10), isInt16List);
+  testInt(new Int32List(10), isInt32List);
+
+  testInt(new Uint8List(10), isUint8List);
+  testInt(new Uint16List(10), isUint16List);
+  testInt(new Uint32List(10), isUint32List);
+
+  testInt(new Uint8ClampedList(10), isUint8ClampedList);
+}
+
+main() {
+  inscrutable = (x) => x;
+  testTypes();
+}
diff --git a/tests/standalone/io/link_async_test.dart b/tests/standalone/io/link_async_test.dart
index d468a31..f310e8c 100644
--- a/tests/standalone/io/link_async_test.dart
+++ b/tests/standalone/io/link_async_test.dart
@@ -140,7 +140,7 @@
 }
 
 
-Future testCreateLoopingLink() {
+Future testCreateLoopingLink(_) {
   return new Directory('').createTemp()
     .then((dir) => dir.path)
     .then((String base) =>
@@ -163,7 +163,7 @@
 }
 
 
-Future testRename() {
+Future testRename(_) {
   Future testRename(String base , String target) {
     Link link1;
     Link link2;
@@ -271,10 +271,45 @@
   return Future.wait(futures);
 }
 
+Future checkExists(String filePath) =>
+    new File(filePath).exists().then(Expect.isTrue);
+
+Future testRelativeLinks(_) {
+  return new Directory('').createTemp().then((tempDirectory) {
+    String temp = tempDirectory.path;
+    String oldWorkingDirectory = Directory.current.path;
+    // Make directories and files to test links.
+    return new Directory(join(temp, 'dir1', 'dir2')).create(recursive: true)
+    .then((_) => new File(join(temp, 'dir1', 'file1')).create())
+    .then((_) => new File(join(temp, 'dir1', 'dir2', 'file2')).create())
+    // Make links whose path and/or target is given by a relative path.
+    .then((_) => new Link(join(temp, 'dir1', 'link1_2')).create('dir2'))
+    .then((_) => Directory.current = temp)
+    .then((_) => new Link('link0_2').create(join('dir1', 'dir2')))
+    .then((_) => new Link(join('dir1', 'link1_0')).create('..'))
+    .then((_) => Directory.current = 'dir1')
+    .then((_) => new Link(join('..', 'link0_1')).create('dir1'))
+    .then((_) => new Link(join('dir2', 'link2_1')).create(join(temp, 'dir1')))
+    .then((_) => new Link(join(temp, 'dir1', 'dir2', 'link2_0'))
+                     .create(join('..', '..')))
+    // Test that the links go to the right targets.
+    .then((_) => checkExists(join('..', 'link0_1', 'file1')))
+    .then((_) => checkExists(join('..', 'link0_2', 'file2')))
+    .then((_) => checkExists(join('link1_0', 'dir1', 'file1')))
+    .then((_) => checkExists(join('link1_2', 'file2')))
+    .then((_) => checkExists(join('dir2', 'link2_0', 'dir1', 'file1')))
+    .then((_) => checkExists(join('dir2', 'link2_1', 'file1')))
+    // Clean up
+    .whenComplete(() => Directory.current = oldWorkingDirectory)
+    .whenComplete(() => tempDirectory.delete(recursive: true));
+  });
+}
+
 main() {
   asyncStart();
   testCreate()
-    .then((_) => testCreateLoopingLink())
-    .then((_) => testRename())
+    .then(testCreateLoopingLink)
+    .then(testRename)
+    .then(testRelativeLinks)
     .then((_) => asyncEnd());
 }
diff --git a/tests/standalone/io/link_test.dart b/tests/standalone/io/link_test.dart
index ccf534a..78aedc8 100644
--- a/tests/standalone/io/link_test.dart
+++ b/tests/standalone/io/link_test.dart
@@ -200,9 +200,41 @@
       (e) => e is LinkException);
 }
 
+checkExists(String filePath) => Expect.isTrue(new File(filePath).existsSync());
+
+testRelativeLinksSync() {
+  Directory tempDirectory = new Directory('').createTempSync();
+  String temp = tempDirectory.path;
+  String oldWorkingDirectory = Directory.current.path;
+  // Make directories and files to test links.
+  new Directory(join(temp, 'dir1', 'dir2')).createSync(recursive: true);
+  new File(join(temp, 'dir1', 'file1')).createSync();
+  new File(join(temp, 'dir1', 'dir2', 'file2')).createSync();
+  // Make links whose path and/or target is given by a relative path.
+  new Link(join(temp, 'dir1', 'link1_2')).createSync('dir2');
+  Directory.current = temp;
+  new Link('link0_2').createSync(join('dir1', 'dir2'));
+  new Link(join('dir1', 'link1_0')).createSync('..');
+  Directory.current = 'dir1';
+  new Link(join('..', 'link0_1')).createSync('dir1');
+  new Link(join('dir2', 'link2_1')).createSync(join(temp, 'dir1'));
+  new Link(join(temp, 'dir1', 'dir2', 'link2_0')).createSync(join('..', '..'));
+  // Test that the links go to the right targets.
+  checkExists(join('..', 'link0_1', 'file1'));
+  checkExists(join('..', 'link0_2', 'file2'));
+  checkExists(join('link1_0', 'dir1', 'file1'));
+  checkExists(join('link1_2', 'file2'));
+  checkExists(join('dir2', 'link2_0', 'dir1', 'file1'));
+  checkExists(join('dir2', 'link2_1', 'file1'));
+    // Clean up
+  Directory.current = oldWorkingDirectory;
+  tempDirectory.deleteSync(recursive: true);
+}
+
 main() {
   testCreateSync();
   testCreateLoopingLink();
   testRenameSync();
   testLinkErrorSync();
+  testRelativeLinksSync();
 }
diff --git a/tools/VERSION b/tools/VERSION
index f9992b5..ebc47a1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 7
-BUILD 3
-PATCH 1
+BUILD 4
+PATCH 0
diff --git a/tools/bots/__init__.py b/tools/bots/__init__.py
new file mode 100644
index 0000000..3479377
--- /dev/null
+++ b/tools/bots/__init__.py
@@ -0,0 +1,4 @@
+# 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.
+
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
new file mode 100644
index 0000000..c506014
--- /dev/null
+++ b/tools/bots/bot_utils.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env 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 hashlib
+import imp
+import os
+import subprocess
+import sys
+
+DART_DIR = os.path.abspath(
+    os.path.normpath(os.path.join(__file__, '..', '..', '..')))
+
+def GetUtils():
+  '''Dynamically load the tools/utils.py python module.'''
+  return imp.load_source('utils', os.path.join(DART_DIR, 'tools', 'utils.py'))
+
+utils = GetUtils()
+
+SYSTEM_RENAMES = {
+  'win32': 'windows',
+  'windows': 'windows',
+  'win': 'windows',
+
+  'linux': 'linux',
+  'linux2': 'linux',
+  'lucid32': 'linux',
+  'lucid64': 'linux',
+
+  'darwin': 'macos',
+  'mac': 'macos',
+  'macos': 'macos',
+}
+
+ARCH_RENAMES = {
+  '32': 'ia32',
+  'ia32': 'ia32',
+
+  '64': 'x64',
+  'x64': 'x64',
+}
+
+class Channel(object):
+  BLEEDING_EDGE = 'be'
+  DEV = 'dev'
+  STABLE = 'stable'
+  ALL_CHANNELS = [BLEEDING_EDGE, DEV, STABLE]
+
+class ReleaseType(object):
+  RAW = 'raw'
+  SIGNED = 'signed'
+  RELEASE = 'release'
+  ALL_TYPES = [RAW, SIGNED, RELEASE]
+
+class Mode(object):
+  RELEASE = 'release'
+  DEBUG = 'debug'
+  ALL_MODES = [RELEASE, DEBUG]
+
+class GCSNamer(object):
+  def __init__(self, channel=Channel.BLEEDING_EDGE,
+      release_type=ReleaseType.RAW):
+    assert channel in Channel.ALL_CHANNELS 
+    assert release_type in ReleaseType.ALL_TYPES
+
+    self.channel = channel
+    self.release_type = release_type
+    self.bucket = 'gs://dart-archive'
+
+  # Functions for quering complete gs:// filepaths
+
+  def version_filepath(self, revision):
+    return '%s/channels/%s/%s/%s/VERSION' % (self.bucket, self.channel,
+        self.release_type, revision)
+
+  def editor_zipfilepath(self, revision, system, arch):
+    return '/'.join([self.editor_directory(revision),
+      self.editor_zipfilename(system, arch)])
+
+  def sdk_zipfilepath(self, revision, system, arch, mode):
+    return '/'.join([self.sdk_directory(revision),
+      self.sdk_zipfilename(system, arch, mode)])
+
+  def dartium_variant_zipfilepath(self, revision, name, system, arch, mode):
+    return '/'.join([self.dartium_directory(revision),
+      self.dartium_variant_zipfilename(name, system, arch, mode)])
+
+  # Functions for querying gs:// directories
+
+  def dartium_directory(self, revision):
+    return self._variant_directory('dartium', revision)
+
+  def sdk_directory(self, revision):
+    return self._variant_directory('sdk', revision)
+
+  def editor_directory(self, revision):
+    return self._variant_directory('editor', revision)
+
+  def editor_eclipse_update_directory(self, revision):
+    return self._variant_directory('editor-eclipse-update', revision)
+
+  def apidocs_directory(self, revision):
+    return self._variant_directory('api-docs', revision)
+
+  def misc_directory(self, revision):
+    return self._variant_directory('misc', revision)
+
+  def _variant_directory(self, name, revision):
+    return '%s/channels/%s/%s/%s/%s' % (self.bucket, self.channel,
+        self.release_type, revision, name)
+
+  # Functions for quering filenames
+
+  def apidocs_zipfilename(self):
+    return 'dart-api-docs.zip'
+
+  def editor_zipfilename(self, system, arch):
+    return 'darteditor-%s-%s.zip' % (
+        SYSTEM_RENAMES[system], ARCH_RENAMES[arch])
+
+  def sdk_zipfilename(self, system, arch, mode):
+    assert mode in Mode.ALL_MODES
+    return 'dartsdk-%s-%s-%s.zip' % (
+        SYSTEM_RENAMES[system], ARCH_RENAMES[arch], mode)
+
+  def dartium_variant_zipfilename(self, name, system, arch, mode):
+    assert name in ['chromedriver', 'dartium', 'content_shell']
+    assert mode in Mode.ALL_MODES
+    return '%s-%s-%s-%s.zip' % (
+        name, SYSTEM_RENAMES[system], ARCH_RENAMES[arch], mode)
+
+def run(command, env=None, shell=False):
+  print "Running command: ", command
+
+  p = subprocess.Popen(command, stdout=subprocess.PIPE,
+                       stderr=subprocess.PIPE, env=env, shell=shell)
+  (stdout, stderr) = p.communicate()
+  if p.returncode != 0:
+    print >> sys.stderr, "Failed to execute '%s'. Exit code: %s." % (
+        command, p.returncode)
+    print >> sys.stderr, "stdout: ", stdout
+    print >> sys.stderr, "stderr: ", stderr
+    raise Exception("Failed to execute %s." % command)
+
+class GSUtil(object):
+  GSUTIL_IS_SHELL_SCRIPT = False
+  GSUTIL_PATH = None
+
+  def _layzCalculateGSUtilPath(self):
+    if not GSUtil.GSUTIL_PATH:
+      buildbot_gsutil = utils.GetBuildbotGSUtilPath()
+      if os.path.isfile(buildbot_gsutil):
+        GSUtil.GSUTIL_IS_SHELL_SCRIPT = True
+        GSUtil.GSUTIL_PATH = buildbot_gsutil
+      else:
+        dart_gsutil = os.path.join(DART_DIR, 'third_party', 'gsutil', 'gsutil')
+        possible_locations = (list(os.environ['PATH'].split(os.pathsep))
+            + [dart_gsutil])
+        for directory in possible_locations:
+          location = os.path.join(directory, 'gsutil')
+          if os.path.isfile(location):
+            GSUtil.GSUTIL_IS_SHELL_SCRIPT = False
+            GSUtil.GSUTIL_PATH = location
+            break
+      assert GSUtil.GSUTIL_PATH
+
+  def execute(self, gsutil_args):
+    self._layzCalculateGSUtilPath()
+
+    env = dict(os.environ)
+    # If we're on the buildbot, we use a specific boto file.
+    if utils.GetUserName() == 'chrome-bot':
+      boto_config = {
+        'linux': '/mnt/data/b/build/site_config/.boto',
+        'macos': '/Volumes/data/b/build/site_config/.boto',
+        'win32': r'e:\b\build\site_config\.boto',
+      }[utils.GuessOS()]
+      env['AWS_CREDENTIAL_FILE'] = boto_config
+      env['BOTO_CONFIG'] = boto_config
+
+    if GSUtil.GSUTIL_IS_SHELL_SCRIPT:
+      gsutil_command = [GSUtil.GSUTIL_PATH]
+    else:
+      gsutil_command = [sys.executable, GSUtil.GSUTIL_PATH]
+
+    run(gsutil_command + gsutil_args, env=env,
+        shell=(GSUtil.GSUTIL_IS_SHELL_SCRIPT and sys.platform == 'win32'))
+
+  def upload(self, local_path, remote_path, recursive=False, public=False):
+    assert remote_path.startswith('gs://')
+
+    args = ['cp']
+    if public:
+      args += ['-a', 'public-read']
+    if recursive:
+      args += ['-R']
+    args += [local_path, remote_path]
+    self.execute(args)
+
+  def remove(self, remote_path, recursive=False):
+    assert remote_path.startswith('gs://')
+
+    args = ['rm']
+    if recursive:
+      args += ['-R']
+    args += [remote_path]
+    self.execute(args)
+
+def CalculateChecksum(filename):
+  """Calculate the MD5 checksum for filename."""
+
+  md5 = hashlib.md5()
+
+  with open(filename, 'rb') as f:
+    data = f.read(65536)
+    while len(data) > 0:
+      md5.update(data)
+      data = f.read(65536)
+
+  return md5.hexdigest()
+
+def CreateChecksumFile(filename, mangled_filename=None):
+  """Create and upload an MD5 checksum file for filename."""
+  if not mangled_filename:
+    mangled_filename = os.path.basename(filename)
+
+  checksum = CalculateChecksum(filename)
+  checksum_filename = '%s.md5sum' % filename
+
+  with open(checksum_filename, 'w') as f:
+    f.write('%s *%s' % (checksum, mangled_filename))
+
+  return checksum_filename
diff --git a/tools/coverage.dart b/tools/coverage.dart
index 15333a6..9958e43 100644
--- a/tools/coverage.dart
+++ b/tools/coverage.dart
@@ -78,7 +78,7 @@
 
   void SetLineInfo(List lineInfoTable) {
     // Each line is encoded as an array with first element being the line
-    // number, followed by pairs of (tokenPosition, textOffset).
+    // number, followed by pairs of (tokenPosition, columnNumber).
     lineInfoTable.forEach((List<int> line) {
       int lineNumber = line[0];
       for (int t = 1; t < line.length; t += 2) {
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 3b71d3c..3b969ac 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -115,6 +115,17 @@
       }
     },
     "Document": {
+      "comment": [
+        "/**",
+        " * The base class for all documents.",
+        " *",
+        " * Each web page loaded in the browser has its own [Document] object, which is",
+        " * typically an [HtmlDocument].",
+        " *",
+        " * If you aren't comfortable with DOM concepts, see the Dart tutorial",
+        " * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).",
+        " */"
+      ],
       "members": {
         "createElement": [
           "/// Deprecated: use new Element.tag(tagName) instead."
@@ -139,6 +150,11 @@
       }
     },
     "Element": {
+      "comment": [
+        "/**",
+        " * An abstract class, which all HTML elements extend.",
+        " */"
+      ],
       "members": {
         "querySelector": [
           "/**",
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 2a063c0..333d747 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -15,6 +15,8 @@
     if (invocation.isGetter) {
       return _data[member];
     } else if (invocation.isSetter) {
+      assert(member.endsWith('='));
+      member = member.substring(0, member.length - 1);
       _data[member] = invocation.positionalArguments[0];
     } else {
       return Function.apply(_data[member], invocation.positionalArguments, invocation.namedArguments);
@@ -94,7 +96,6 @@
   static window() native "Utils_window";
   static forwardingPrint(String message) native "Utils_forwardingPrint";
   static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
-  static void spawnDomUri(String uri, int replyTo) native "Utils_spawnDomUri";
   static int _getNewIsolateId() native "Utils_getNewIsolateId";
 
   // The following methods were added for debugger integration to make working
@@ -133,7 +134,9 @@
    * expression for a closure with a body matching the original expression
    * where locals are passed in as arguments. Returns a list containing the
    * String expression for the closure and the list of arguments that should
-   * be passed to it.
+   * be passed to it. The expression should then be evaluated using
+   * Dart_EvaluateExpr which will generate a closure that should be invoked
+   * with the list of arguments passed to this method.
    *
    * For example:
    * <code>wrapExpressionAsClosure("foo + bar", ["bar", 40, "foo", 2])</code>
@@ -146,6 +149,12 @@
     addArg(arg, value) {
       arg = stripMemberName(arg);
       if (args.containsKey(arg)) return;
+      // We ignore arguments with the name 'this' rather than throwing an
+      // exception because Dart_GetLocalVariables includes 'this' and it
+      // is more convenient to filter it out here than from C++ code.
+      // 'this' needs to be handled by calling Dart_EvaluateExpr with
+      // 'this' as the target rather than by passing it as an argument.
+      if (arg == 'this') return;
       if (args.isNotEmpty) {
         sb.write(", ");
       }
@@ -366,8 +375,28 @@
   bool get isNotEmpty => Maps.isNotEmpty(this);
 }
 
+// TODO(vsm): Remove DOM isolate code.  This is only used to support
+// printing and timers in background isolates.  Background isolates
+// should just forward to the main DOM isolate instead of requiring a
+// special DOM isolate.
+
+_makeSendPortFuture(spawnRequest) {
+  final completer = new Completer<SendPort>.sync();
+  final port = new ReceivePort();
+  port.receive((result, _) {
+    completer.complete(result);
+    port.close();
+  });
+  // TODO: SendPort.hashCode is ugly way to access port id.
+  spawnRequest(port.toSendPort().hashCode);
+  return completer.future;
+}
+
+Future<SendPort> _spawnDomFunction(Function f) =>
+    _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
+
 final Future<SendPort> __HELPER_ISOLATE_PORT =
-    spawnDomFunction(_helperIsolateMain);
+    _spawnDomFunction(_helperIsolateMain);
 
 // Tricky part.
 // Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
diff --git a/tools/dom/src/native_DOMPublic.dart b/tools/dom/src/native_DOMPublic.dart
index 5e96fcd..f38c63d 100644
--- a/tools/dom/src/native_DOMPublic.dart
+++ b/tools/dom/src/native_DOMPublic.dart
@@ -4,25 +4,6 @@
 
 part of html;
 
-_makeSendPortFuture(spawnRequest) {
-  final completer = new Completer<SendPort>.sync();
-  final port = new ReceivePort();
-  port.receive((result, _) {
-    completer.complete(result);
-    port.close();
-  });
-  // TODO: SendPort.hashCode is ugly way to access port id.
-  spawnRequest(port.toSendPort().hashCode);
-  return completer.future;
-}
-
-// This API is exploratory.
-Future<SendPort> spawnDomFunction(Function f) =>
-    _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
-
-Future<SendPort> spawnDomUri(String uri) =>
-    _makeSendPortFuture((portId) { _Utils.spawnDomUri(uri, portId); });
-
 // testRunner implementation.
 // FIXME: provide a separate lib for testRunner.
 
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index eba39e5..bf62f8b 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -133,6 +133,3 @@
 _callPortSync(int id, message) {
   return JS('var', r'ReceivePortSync.dispatchCall(#, #)', id, message);
 }
-
-Future<SendPort> spawnDomFunction(Function f) =>
-  new Future.value(IsolateNatives.spawnDomFunction(f));
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index effda9d..90c3dfa 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -4,15 +4,7 @@
 
 part of $LIBRARYNAME;
 
-/**
- * The base class for all documents.
- *
- * Each web page loaded in the browser has its own [Document] object, which is
- * typically an [HtmlDocument].
- *
- * If you aren't comfortable with DOM concepts, see the Dart tutorial
- * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
- */
+@DocsEditable
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME extends Node $NATIVESPEC
 {
 
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 6cf45d4..8f73476 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -301,9 +301,7 @@
 $!ELEMENT_STREAM_GETTERS
 }
 
-/**
- * An abstract class, which all HTML elements extend.
- */
+@DocsEditable
 $(ANNOTATIONS)abstract class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
   /**
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index b797f0b..1e5c50b 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -4,6 +4,7 @@
 
 part of $LIBRARYNAME;
 
+@DocsEditable
 $if DART2JS
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "Window,DOMWindow" {
 $else